DACP
DACP is another apple Protocol. This one is used to control iTunes remotely (playing music on the iTunes computer as opposed to sending it to the client computer). Other implementations are MonkeyTunes for MediaMonkey and (my) Telescope plugin for songbird.
This documentation is meant to describe the workings of DACP in sufficient detail for others to copy to make clients and servers.
Overview
DACP uses the same protocol as DAAP, and this is described well at http://tapjam.net/daap/. It is basically HTTP requests and responses, with data passed in a binary format. a javascript module designed to encode and decode is available at http://songbird-telescope.googlecode.com/svn/trunk/modules/DMAP.js.
Pairing Process
The pairing process is quite tricky. it uses a couple of services advertised by bonjour (zeroconf).
With the client and server running, the server is broadcasting a _touch-able._tcp service. This is mainly for clients that are already paired to find it, but can be used to display a list of possible servers to a client. This service contains a hex service name string, and the name of the server in a CtlN txt record.
The user starts the pairing process on the client, which announces a _touch-remote._tcp service, which the server is listening for. The client also gives the user a 4 digit numeric code. When the server finds one of these client services it collects the DvNm (device name) and Pair txt records and asks the user to input a 4 digit code. This code is then combined with the pairing code as below (information from Micheal Bailey).
Take the pairing code, append the first digit, then a null byte, then second digit, null byte, third digit, null byte, fourth digit, null byte. So (- = NULL)
pairingcode1-2-3-4-
Then md5 Hash this byte array, and put it in upper case. This is now returned in a HTTP request to the client (so the client needs a HTTP server as well!) /pair?pairingcode=CODE&servicename=SERVERSERVICENAME
Note the service name is the Server's hex string used in the bonjour service description.
The client also generates this hash using the same method, and compares the results. If they match it sends a response giving another pairing guid. It can store the service name for future reference. The pairing process is complete and the login process begins.
Example _touch-able._tcp Bonjour Service Description
Service Name: D41D8CD98F00B204
Type: _touch-able._tcp
Domain: local.
Host: Server.local.
Port: 3689
TxtRecord:
txtvers=1
OSsi=0x10313
CtlN=Songbird Library
Ver=131073
DvSv=2305
DvTy=iTunes
DbId=D41D8CD98F00B204
Example _touch-remote._tcp Bonjour Service Descriptoon
Service Name: e01d387addad7a7d703f7936f92e804a53d202b7
Type: _touch-remote._tcp
Domain: local.
Host: iPod-4.local.
Port: 50006
TXTRecord:
DvNm=Tom’s iPod
Pair=82244618866AA140
RemV=10000
txtvers=1
RemN=Remote
DvTy=iPod touch
Login Process
The login process begins on the client. It looks up the service name it got from the pairing process and gets the address and port of the server. It then begins a HTTP request. The first request is /server-info, to get basic server data. The next request is to /login, where it gives the pairing guid it gave in the pairing process, this allows the server to know the client has already completed the pairing process and gives it access. This is different to the login mechanism for DAAP, even though a lot of the commands are the same. I handle this in Telescope by allowing either a DAAP HTTP-Authentication login or a DACP login for DAAP commands, but only a DACP login for DACP commands that change things on the server (start stop music etc).
Once you've logged in you can do what you like, iTunes does the following: /databases, for a list of (only ever seen 1) databases on the server. then /databases/«dbid»/containers (which may be called multiple times?!). See below for notes on this request.
Details of individual URLs
/databases/<<dbid>>/containers
DAAP/DACP
This requests a list of every container in the database. This includes nested containers (such as those in folders). However what makes this special is that it also needs to include the 2 extra containers. The Database container and the all music container.
The database container is a special 'base' playlist that (presumably) includes everything available on the server. iTunes returns it as the first container in the list and it contains the abpl=true tag. This is important as the next step is for iTunes to ask for a list of things in this database with a songalbumid:0 filter. I don't know what would have a songalbumid:0 as iTunes always returns an empty list, so Telescope does too. iTunes also includes meds=0 (not editable).
The second playlist is an all music playlist. This represents the basic view in iTunes, and includes all music in the library (but not podcasts videos etc). Extra metadata included for this playlist: aeSP:1, aePS:6, meds:0
Containers that aren't in folders have mtco=0 (parent container id), otherwise mtco=(miid of parent container).
.../containers/<<id>>/items
DAAP/DACP
Requests a list of all items in a container (can also request all items from the database directly with /databases/«dbid»/items ).
/ctrl-int/1/cue?command=<<>>&query=<<>>&index=<<>>...
This is a type of play command. A list of songs is generated by applying the query
parameter to the database, then this is played (if command
= play) starting at position index
(0-based). Note index is a single number (e.g. index=1), not a range like in requests for lists. Further parameters may be included to set other properties.
/ctrl-int/1/items
Not in iTunes, Songbird Telescope plugin only
returns a list of items that are in the currently playing playlist. Same response as a standard container/«id»/items
request.