iRATE External Control Plugin
Protocol definition
Robin Sheat
The protocol is an XML based protocol to allow for extensibility, and to match the rest of iRATE. It has basic passwording support and the ability to only allow connections from localhost to allow a level of security.
For the purposes of this, the two components are labled irate-client (effectively the server in this situation), and remote app (effectively the client).
A Perl test program for this can be found here. It provides a reference for other programs.
Revision History:
- Robin - 17/8/2003: First draft
- Robin - 18/8/2003: Added notes on reponses to improper XML, disconnect command, plugin added to iRATE CVS.
- Robin - 19/8/2003: Added link to test program, changed the XML element cases to match the rest of iRATE. [Note: This may break existing programs.]. Fixed a documentation bug regarding the XML element name for responses.
- Robin - 20/8/2003: Added invert-pause, removed comment about one connection at a time, as it is no longer true.
- Robin - 21/8/2003: Added section on authorisation.
- Robin - 30/3/2005: Added skiptounrated function
Connection
The default port that the plugin listens on is 12473. The remote app connects on this port.
Authorisation
Because there may be times when you don't want everyone to be able to mess with your player, but you do want to be able to remote control it, we need an authorisation system, in this case, password-based.
If passwords are turned off, then this section can be safely ignored. If a client wishes to determine if passwords are required, it should just issue any command. It will either get the expected reply, indicating no password is needed. Otherwise it will receive a login-required response (see below).
The XML element names are the same as defined below, Command for remote app -> irate-client, IrateClient for irate-client -> remote app communications.
There are two types of login: plaintext and digest.
Plaintext authorisation
- type
- login
- format
- plaintext
- password
- the plaintext password
This is suitable for use in basic scripts, where you don't want to play around with challenge/response, but is less secure. The login XML is simply:
Digest authorisation (MD5)
- type
- login
- format
- digest-md5-getchallenge
This should be the first request. The irate-client will reply with:
- type
- login-challenge
- challenge
- a string of characters
The remote app should respond with:
- type
- login
- format
- digest-md5
- password
- the hashed password and challenge as defined below.
This is a more secure, but also more complex, method. The challenge returned by the irate-client will be a sequence of characters that should be appended to the plaintext password. This resulting string should then be hashed using MD5, and sent. Note that the MD5 is hex encoded, not base64 like is also common.
Authorisation responses
Four responses are valid from the irate-client, plus the same responses to invalid XML in the last section.
Login success
- type
- login-success
After this, the remote app can begin using the commands below.
Login failure
- type
- login-failure
Generally an incorrect password. The connection will be dropped after this is sent.
Login protocol error
- type
- login-protocol-error
This is sent if the irate-client gets confused by the input. Something along the lines of a digest password getting sent without a challenge, or a challenge being requested twice will cause this. The connection will be dropped after this.
Format not implemented
- type
- login-format-not-implemented
This is sent to allow future extension of the login method. It is sent if the format attribute contains an unknown string. The irate-client treats this as though nothing happened, allowing the remote app to try a different method.
Login required
- type
- login-required
This results from any command being issued without the type attribute being set to login.
Commands from the remote app
Once connected, the remote app sends a command to the irate-client. Presently there is no situation where the irate-client will send anything to the remote app unsolicited.
All commands have the XML name Command.
The following lists the attribute names and the value they should be set to to specify the request.
Request current track info
- type
- currenttrack
The irate-client will respond with a trackinfo XML element detailing the currently playing track. This is documented below.
Request player state
- type
- playerstate
The irate-client will respond with a playerstate XML element.
Request selected track info
- type
- selectedtrack
The irate-client will respond with a trackinfo XML element detailing the track that is selected in the UI. In some players, this is always the same as the currently playing track.
Pause the player
- type
- pause
Pauses playback. No reponse from the irate-client
Unpause the player
- type
- unpause
Unpauses playback. Note that neither this nor the pause function are toggles. Pausing an already paused player has no effect.
Toggle pause
- type
- invert-pause
Toggles the paused state of the player.
Skip to the next song
- type
- skip
Skips to the next song. The irate-client will respond with a trackinfo XML element of the new song. Skipping the player when it is paused will unpause it.
Skip to the next unrated song
- type
- skiptounrated
Skips to the next unrated song. The irate-client will respond with a trackinfo XML element of the new song. Skipping the player when it is paused will unpause it. If there are no unrated tracks on the playlist, then it behaves just like skip.
Set rating of playing track
- type
- rateplaying
- rate
- An integer from 0 to 10
Sets the rating of the currently playing track. As this may cause the current track information to change, a trackinfo XML element is returned containing the currently playing track.
Set rating of selected track
- type
- rateselected
- rate
- An integer from 0 to 10
Sets the rating of the currently selected track. A trackinfo XML element is returned that contains the currently selected track. Note that this may also cause the playing track to change. It is up to the remote app to update itself of that.
Disconnect
- type
- disconnect
A polite way of requesting a disconnect. Generally has the same effect as just dropping the connection, but nicer. The irate-client silently closes the connection.
Irate-client responses
All responses have the XML name IrateClient.
Track info
- type
- trackinfo
- source
- selected, playing, or empty.
- title
- string containing the track title
- artist
- string containing the track artist
- url
- string containing the URL the file was downloaded from
- filename
- the filename iRATE uses to access the file
- state
- the state of the file: Broken, Not Downloaded, Missing, Unrated, or its rating
- rating
- the actual rating
- numtimes
- number of times played
- lastplayed
- when it was last played
This returns the above information on the track, which is in response to the requests above. Note that this packet is not send automatically on events such as track change. The remote app should query every so often if it requires that information. This may change in the future.
Player state
- type
- playerstate
- play
- 1 if playing, 0 if paused.
Invalid commands
If invalid XML (i.e. something that is not really XML), or an XML element with an invalid name is received, an invalid-command XML response is sent, and the connection is broken.
If an XML element with a correct name, but invalid command is received, an unknown-command response is sent, and the connection remains open.
In these, the fatal attribute tells the client whether or not the connection will be broken. Not strictly necessary, but polite.
Invalid-command response
- type
- error
- errorcondition
- invalid-command
- fatal
- 1
Connection dropped.
Unknown-command response
- type
- error
- errorcondition
- unknown-command
- fatal
- 0
Connection not dropped.