Apple Accessory Protocol
From wikiPodLinux
The Apple Accessory Protocol is used for communication between the iPod and serially connected accessories (such as the Remote, iTalk etc). The protocol was introduced with the 3rd generation iPods, and at present it is assumed is also compatible with the 4th generation iPods and mini iPods. (The Dock Connector provides access to this communication channel as well.)
The connections uses a standard 8N1 serial protocol. The original speed rate is 19200 baud - higher rates (up to 57600 baud) work properly (tested the 5G) but make trouble sending large amounts of data (picture blocks) faster than 38400 baud.
Table of contents |
Request/Response Structure
The request and response messages follow this general form.
field | size | value |
---|---|---|
header | 2 | 0xff 0x55 |
length | 1 | size of mode + command + parameter |
mode | 1 | the mode the command is referring to |
command | 2 | the two byte command |
parameter | 0..n | optional parameter, depending on the command |
checksum | 1 | 0x100 - ( (sum of all length/mode/command/parameter bytes) & 0xFF) |
The mode in the message indicates which mode the command belongs to, these same mode values are used in the mode switching command below.
Mode List
Mode Number | Purpose |
---|---|
0x00 | Mode switching |
0x01 | Voice Recorder |
0x02 | Simple Remote |
0x03 | Request Mode Status |
0x04 | AiR Mode |
Mode Switching (Mode 0)
Command | Purpose |
---|---|
0x01 0x01 | Switch to Voice Recorder mode, not working on G5 |
0x01 0x02 | Switch to iPod Remote mode |
0x01 0x04 | Switch to AiR mode |
0x03 | Get current mode status |
0x04 xx | (response) the current mode number (xx is the mode returned by the iPod), 0x04 0x01 could also be an indicator that the iPod is currently busy - I frequently get this skipping tracks very fast --- this info is not 100% correct, I´m getting different responses. Will try to work this out later. |
0x05 | Switch to AiR mode (same as 0x01 0x04?) |
0x06 | Switch to iPod Remote mode (same as 0x01 0x02?) |
Clearly there's stuff here waiting to be figured out.
Voice Memo (Mode 1)
The mode 1 commands are used for the voice recording functions. To initiate the recording mode on the iPod the send the switch to mode 0x01 command - this will switch the iPod display to the "Voice Memo" screen. When the record button is pressed the iPod will send the command "0x00 0x00", sending the command to switch to mode 0x01 will start the actual recording.
Command | Purpose |
---|---|
0x01 0x00 | Recording has started. |
0x01 0x01 | Recording has stopped (or paused). |
iPod Remote (Mode 2)
The mode 2 commands are used by the remote control to signal button presses. When a button is pressed the appropriate code is send 66 times per second until the button is released at which point the button released command is sent.
Note that the 3 and 4 byte commands may not work for older (tested on a 3g) iPods. They are valid for newer (tested on an iPod Nano) iPods however.
Command | Purpose |
---|---|
0x00 0x00 | Button Released |
0x00 0x01 | Play |
0x00 0x02 | Vol+ |
0x00 0x04 | Vol- |
0x00 0x08 | Skip> |
0x00 0x10 | Skip< |
0x00 0x20 | Next Album |
0x00 0x40 | Previous Album |
0x00 0x80 | Stop |
0x00 0x00 0x01 | Play (just play, no pause) |
0x00 0x00 0x02 | Pause (just pause, no play) |
0x00 0x00 0x04 | Mute (toggle) |
0x00 0x00 0x20 | Next Playlist |
0x00 0x00 0x40 | Previous Playlist |
0x00 0x00 0x80 | Toggles Shuffle |
0x00 0x00 0x00 0x01 | Toggles Repeat |
0x00 0x00 0x00 0x04 | Ipod Off |
0x00 0x00 0x00 0x08 | Ipod On |
0x00 0x00 0x00 0x40 | Menu Button |
0x00 0x00 0x00 0x80 | OK/Select Button |
0x00 0x00 0x00 0x00 0x01 | Scroll Up |
0x00 0x00 0x00 0x00 0x02 | Scroll Down |
Advanced Remote (Mode 4)
The mode 4 commands are used for the Advanced iPod Remote (AiR) functions. The commands can be used to remotely control much of the iPod functions. Unfortunately when switched to this mode the iPod display changes to "OK to disconnect".
Commands you send to the iPod are in bold, responses to those commands from the iPod are not. The response is always the command + 1.
Command | Parameter (bytes) | Purpose |
---|---|---|
0x00 0x00 | Result(1) Command(2) | think that the result 0x04 means that the command wasn´t understood |
0x00 0x01 | Result(1) Command(2) | Gives you feedback on the command you just executed. Result: 0=success, 2=failure, 4=you exceeded the limit of whatever you were requesting/wrong parameter-count, 5=sent an iPod-Answere-Cmd(?). The Command is the command that this is in response to. |
0x00 0x02 | none | perhaps a simple ping-request ?! |
0x00 0x03 | 8 bytes | 0xFF 0xFF 0xFF 0xFF 0x00 0x00 0x00 0x00 (echo?) | 0x00 0x09 | none | ? returns flag set with 0x00 0x0b, don´t know, what this means (perhaps an indicator for track-change - if you set this flag to 0x01 it turns to 0x00 again after changing the track) |
0x00 0x0a | 1 byte | 0x00 or 0x01 | 0x00 0x0b | 1 byte | parameter 0x00 & 0x01 result in a success-answere (copare 0x00 0x01), don´t know what happens - seems to be a flag which can be read with 0x00 0x09 | 0x00 0x0c | 7 bytes | ??? results in a answer 0x0d | 0x00 0x0d | 11 bytes or 1 byte | tried some parameters - result seems to dependent on current playlist parameters 0x00 0x00 0x00 0x00 0x00 0x00 0x00 give (on my Ipod) 11 bytes (0x00 0x00 0x00 0x00 0x00 0x00 0x02 0xf0 0xdb 0x00 0x00 in main-Playlist - *not* the playlist-number and *not* the count of tracks in this playlist) This command can also inform the accessory when there is a track change (one song ends and another begins). So it is a "subscription" - some previous query caused the ipod to send this every time the track changes. Probably the parameter bytes are a kind of track ID, maybe based on some filesystem attribute, such as actual position on the hard disk. |
0x00 0x12 | none | ? Get iPod Type Size ? |
0x00 0x13 | 2 bytes | Gen3 20GB: 0x01 0x02 (0x01 = Gen3 iPod, 0x02 = 20GB ??) Gen4 30GB: 0x01 0x09 Gen5 30GB: 0x01 0x09 |
0x00 0x14 | none | Get iPod Name |
0x00 0x15 | namestring(var) | iPod Name as a null terminated string |
0x00 0x16 | none | Switch to the main library playlist (playlist 0) |
0x00 0x17 | type(1) number(4) | Switch to item identified by the number and type given. |
0x00 0x18 | type(1) | Get Count of the given types (count of playlists, etc) |
0x00 0x19 | number(4) | Amount of requested type returned |
0x00 0x1A | type(1) number(4) number(4) | Get Names for a range of items, first number is starting item offset (0 for the first item), second number is number of items to retrieve. The iPod will send back an entire message for each item requested. |
0x00 0x1B | number(4) string | offset, name of the item (note that playlist 0 is the "main library" and will contain all the songs on the iPod and have the same name as the iPod itself as in command 0x00 0x14). |
0x00 0x1C | none | Get time and status info |
0x00 0x1D | length(4) time(4) status(1) | Track length in milliseconds, elapsed time in milliseconds, status=0x0 stop, 0x01 playing, 0x02 paused |
0x00 0x1E | none | Get current position in playlist |
0x00 0x1F | position(4) | Current position in playlist |
0x00 0x20 | number(4) | Get title of a song number |
0x00 0x21 | string | title returned as a null terminated string |
0x00 0x22 | number(4) | Get artist of a song number |
0x00 0x23 | string | Artist returned as a null terminated string |
0x00 0x24 | number(4) | Get album of a song number |
0x00 0x25 | string | Album returned as a null terminated string |
0x00 0x26 | pollingmode(1) | Start Polling Mode = 0x01, Stop Polling Mode = 0x00. Polling mode causes the iPod to return the time elapsed (0x00 0x27) every 500 milliseconds. |
0x00 0x27 | number(4) | time elapsed on current song |
0x00 0x28 | number(4) | Execute Playlist switch specified in command 0x00 0x17, and jump to specified songnumber in the playlist (0xFFFFFFFF = start at the beginning of the playlist, even when shuffled... probably what you want to use) |
0x00 0x29 | command(1) | AiR Playback Control. Play/Pause=0x01, Stop=0x02, Skip++=0x03, Skip--=0x04, FFwd=0x05, FRwd=0x06, StopFF/RW=0x07 |
0x00 0x2C | none | Get Shuffle Mode |
0x00 0x2D | shufflemode(1) | Returns current Shuffle mode: Off = 0x00, Songs = 0x01, Albums = 0x02 |
0x00 0x2E | shufflemode(1) | Sets the shuffle mode. Off = 0x00, Songs = 0x01, Albums = 0x02. |
0x00 0x2F | none | Get Repeat Mode |
0x00 0x30 | repeatmode(1) | Returns current Repeat mode: Off = 0x00, One song = 0x01, All songs = 0x02 |
0x00 0x31 | repeatmode(1) | Sets the repeat mode. Off = 0x00, One song = 0x01, All songs = 0x02 |
0x00 0x32 | Picture Blocks | Upload Picture for AiR mode (see picture block description below) |
0x00 0x33 | none | ? Get Max Screen Size for Picture Upload ? |
0x00 0x34 | 2+2+1 bytes | Gen3 20GB: 0x00 0x78 0x00 0x41 0x01 => 120 x 65 ? Gen5 30GB: 0x01 0x36 0x00 0xa8 0x01 => 310 x 168 ? |
0x00 0x35 | none | Get number of songs in current playlist |
0x00 0x36 | number(4) | Number of songs in current playlist |
0x00 0x37 | number(4) | Jump to specified Songnumber in the current playlist |
0x00 0x38 | none | ??? |
0x00 0x39 | 2*(2+2+1) = 10 bytes | ?? Gen5 30GB: 0x01 0x36 0x00 0xa8 0x02 0x01 0x36 0x00 0xa8 0x03 ... some similarities to 0x00 0x34 perhaps different solutions for different colordepth? |
Type | Purpose |
---|---|
0x01 | Playlist |
0x02 | Artist |
0x03 | Album |
0x04 | Genre |
0x05 | Song |
0x06 | Composer |
Picture Blocks
Transferring a picture to the iPod's screen is done using picture blocks. A picture block is basically the picture command (0x00 0x32). It's complicated enough to deserve its own section.
The parameter bytes of a picture block look like the following:
field | size | value |
---|---|---|
block number | 2 | number of the block (starting from zero) |
unknown | 1 | always 1, only in the first block |
width | 2 | width of the picture, only in the first block |
height | 2 | height of the picture, only in the first block |
bytes per line | 4 | number of bytes you will send for each line. Divisible by 4, and only in the first block |
picture bytes | N | 3 lines? of pixels to be displayed, every 2 bits represents a pixel (4 color greyscale) |
An example would look something like the following:
First block:
0xFF 0x55 (standard header) 0x6E (length of data in this block) 0x04 (mode of the command) 0x00 0x32 (command for picture display) 0x00 0x00 (indicates the first block (block zero)) 0x01 (damned if I know.. perhaps indicates that the size info for the picture is here) 0x00 0x78 (width of picture to be displayed) 0x00 0x40 (height of picture to be displayed) 0x00 0x00 0x00 0x20 (number of bytes you're sending for each line of the display - must be a multiple of 8 and has to fit the needed bits!) The rest is a 4 color picture, with every two bits representing a pixel. Checksum.
Second block and every block thereafter:
0xFF 0x55 (standard header) 0x65 (length of data in this block) 0x04 (mode of the command) 0x00 0x32 (command for picture display) 0x00 0x01 (indicates the second block (increment as you go)) The rest is a 4 color picture, with every two bits representing a pixel. Checksum.
Any extra pixels you send outside the range of the picture size on the right or bottom of the picture then get cut off.
You can see if the command was valid when you watch the response string for each block.
Good response is 0xFF 0x55 0x06 0x04 0x00 0x01 0x00 0x00 0x32 0xC3.
Bad response 0xFF 0x55 0x06 0x04 0x00 0x01 0x04 0x00 0x32 0xBF.
Below a width of 0x10 fillbits are used (only every 4th nibble of the picturedata is taken for the picture).