rockbox/apps/iap/iap-lingo4.c
William Wilgus 687767bd8f convert a few more strlcpy to strmemccpy calls Fix Red and Yellow
albumart is imported to plugins just use a macro substitution
for now

Change-Id: I7c2e10d7559c087f0b3d0e6b844027d3b323da55
2022-11-15 01:24:26 -05:00

3153 lines
149 KiB
C
Raw Blame History

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Alan Korr & Nick Robinson
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
******************************************************************************/
#include "iap-core.h"
#include "iap-lingo.h"
#include "dir.h"
#include "settings.h"
#include "filetree.h"
#include "wps.h"
#include "playback.h"
#include "string-extra.h"
/*
* This macro is meant to be used inside an IAP mode message handler.
* It is passed the expected minimum length of the message buffer.
* If the buffer does not have the required lenght an ACK
* packet with a Bad Parameter error is generated.
*/
#define CHECKLEN(x) do { \
if (len < (x)) { \
cmd_ack(cmd, IAP_ACK_BAD_PARAM); \
return; \
}} while(0)
/* Check for authenticated state, and return an ACK Not
* Authenticated on failure.
*/
#define CHECKAUTH do { \
if (!DEVICE_AUTHENTICATED) { \
cmd_ack(cmd, IAP_ACK_NO_AUTHEN); \
return; \
}} while(0)
/* Used to remember the last Type and Record requested */
static char cur_dbrecord[5] = {0};
/* Used to remember the total number of filtered database records */
static unsigned long dbrecordcount = 0;
/* Used to remember the LAST playlist selected */
static unsigned long last_selected_playlist = 0;
static void cmd_ack(const unsigned int cmd, const unsigned char status)
{
IAP_TX_INIT4(0x04, 0x0001);
IAP_TX_PUT(status);
IAP_TX_PUT_U16(cmd);
iap_send_tx();
}
#define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK)
static void get_playlist_name(unsigned char *dest,
unsigned long item_offset,
size_t max_length)
{
if (item_offset == 0) return;
DIR* dp;
struct dirent* playlist_file = NULL;
dp = opendir(global_settings.playlist_catalog_dir);
char *extension;
unsigned long nbr = 0;
while ((nbr < item_offset) && ((playlist_file = readdir(dp)) != NULL))
{
/*Increment only if there is a playlist extension*/
if ((extension=strrchr(playlist_file->d_name, '.')) != NULL){
if ((strcmp(extension, ".m3u") == 0 ||
strcmp(extension, ".m3u8") == 0))
nbr++;
}
}
if (playlist_file != NULL) {
strmemccpy(dest, playlist_file->d_name, max_length);
}
closedir(dp);
}
static void seek_to_playlist(unsigned long index)
{
unsigned char selected_playlist
[sizeof(global_settings.playlist_catalog_dir)
+ 1
+ MAX_PATH] = {0};
strcpy(selected_playlist,
global_settings.playlist_catalog_dir);
int len = strlen(selected_playlist);
selected_playlist[len] = '/';
get_playlist_name (selected_playlist + len + 1,
index,
MAX_PATH);
ft_play_playlist(selected_playlist,
global_settings.playlist_catalog_dir,
strrchr(selected_playlist, '/') + 1,
false);
}
static unsigned long nbr_total_playlists(void)
{
DIR* dp;
unsigned long nbr_total_playlists = 0;
struct dirent* playlist_file = NULL;
char *extension;
dp = opendir(global_settings.playlist_catalog_dir);
while ((playlist_file = readdir(dp)) != NULL)
{
/*Increment only if there is a playlist extension*/
if ((extension=strrchr(playlist_file->d_name, '.')) != NULL)
{
if ((strcmp(extension, ".m3u") == 0 ||
strcmp(extension, ".m3u8") == 0))
{
nbr_total_playlists++;
}
}
}
closedir(dp);
return nbr_total_playlists;
}
void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
{
unsigned int cmd = (buf[1] << 8) | buf[2];
/* Lingo 0x04 commands are at least 3 bytes in length */
CHECKLEN(3);
/* Lingo 0x04 must have been negotiated */
if (!DEVICE_LINGO_SUPPORTED(0x04)) {
#ifdef LOGF_ENABLE
logf("iap: Mode04 Not Negotiated");
#endif
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
return;
}
/* All these commands require extended interface mode */
if (interface_state != IST_EXTENDED) {
#ifdef LOGF_ENABLE
logf("iap: Not in Mode04 Extended Mode");
#endif
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
return;
}
switch (cmd)
{
case 0x0001: /* CmdAck. See above cmd_ack() */
/*
* The following is the description for the Apple Firmware
* The iPod sends this telegram to acknowledge the receipt of a
* command and return the command status. The command ID field
* indicates the device command for which the response is being
* sent. The command status indicates the results of the command
* (success or failure).
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x06 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x01 Command ID (bits 7:0)
* 6 0xNN Command result status. Possible values are:
* <20>0x00 = Success (OK)
* 0x01 = ERROR: Unknown database category
* <20>0x02 = ERROR: Command failed
* 0x03 = ERROR: Out of resources
* 0x04 = ERROR: Bad parameter
* 0x05 = ERROR: Unknown ID
* 0x06 = Reserved
* 0x07 = Accessory not authenticated
* <20>0x08 - 0xFF = Reserved
* 7 0xNN The ID of the command being acknowledged (bits 15:8).
* 8 0xNN The ID of the command being acknowledged (bits 7:0).
* 9 0xNN Telegram payload checksum byte
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0002: /* GetCurrentPlayingTrackChapterInfo */
/* The following is the description for the Apple Firmware
* Requests the chapter information of the currently playing track.
* In response, the iPod sends a
* Command 0x0003: ReturnCurrentPlayingTrackChapterInfo
* telegram to the device.
* Note: The returned track index is valid only when there is a
* currently playing or paused track.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x02 Command ID (bits 7:0)
* 6 0xF7 Telegram payload checksum byte
*
* We Return that the track does not have chapter information by
* returning chapter index -1 (0xFFFFFFFF) and chapter count 0
* (0x00000000)
*/
{
unsigned char data[] = {0x04, 0x00, 0x03,
0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0003: /* ReturnCurrentPlayingTrackChapterInfo. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the chapter information of the currently playing track.
* The iPod sends this telegramin response to the
* Command 0x0002: GetCurrentPlayingTrackChapterInfo
* telegram from the device. The track chapter information includes
* the currently playingtrack's chapter index,as well as the
* total number of chapters in the track. The track chapter and the
* total number of chapters are 32-bit signed integers. The chapter
* index of the firstchapter is always 0x00000000. If the track does
* not have chapter information, a chapter index of -1(0xFFFFFFFF)
* and a chapter count of 0 (0x00000000) are returned.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0B Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x03 Command ID (bits 7:0)
* 6 0xNN Current chapter index (bits 31:24)
* 7 0xNN Current chapter index (bits 23:16)
* 8 0xNN Current chapter index (bits 15:8)
* 9 0xNN Current chapter index (bits 7:0)
* 10 0xNN Chapter count (bits 31:24)
* 11 0xNN Chapter count (bits 23:16)
* 12 0xNN Chapter count (bits 15:8)
* 13 0xNN Chapter count (bits 7:0)
* 14 0xNN Telegram payload checksum byte
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0004: /* SetCurrentPlayingTrackChapter */
/* The following is the description for the Apple Firmware
*
* Sets the currently playing track chapter.You can send the Command
* 0x0002: GetCurrentPlayingTrackChapterInfo telegram to get the
* chapter count and the index of the currently playing chapter in
* the current track. In response to the command
* SetCurrentPlayingTrackChapter, the iPod sends an ACK telegram
* with the command status.
*
* Note: This command should be used only when the iPod is in a
* playing or paused state. The command fails if the iPod is stopped
* or if the track does not contain chapter information.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x04 Command ID (bits 7:0)
* 6 0xNN Chapter index (bits 31:24)
* 7 0xNN Chapter index (bits 23:16)
* 8 0xNN Chapter index (bits 15:8)
* 9 0xNN Chapter index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
* We don't do anything with this as we don't support chapters,
* so just return BAD_PARAM
*/
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0005: /* GetCurrentPlayingTrackChapterPlayStatus */
/* The following is the description for the Apple Firmware
*
* Requests the chapter playtime status of the currently playing
* track. The status includes the chapter length and the time
* elapsed within that chapter. In response to a valid telegram, the
* iPod sends a Command 0x0006:
* ReturnCurrentPlayingTrackChapterPlayStatus telegram to the
* device.
*
* Note: If the telegram length or chapter index is invalid for
* instance, if the track does not contain chapter information the
* iPod responds with an ACK telegram including the specific error
* status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x05 Command ID (bits 7:0)
* 6 0xNN Currently playingchapter index (bits31:24)
* 7 0xNN Currently playingchapter index (bits23:16)
* 8 0xNN Currently playing chapter index (bits 15:8)
* 9 0xNN Currently playing chapter index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
* The returned data includes 4 bytes for Chapter Length followed
* by 4 bytes of elapsed time If there is no currently playing
* chapter, length and elapsed are 0
* We don't do anything with this as we don't support chapters,
* so just return BAD_PARAM
*/
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0006: /* ReturnCurrentPlayingTrackChapterPlayStatus. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the play status of the currently playing track chapter.
* The iPod sends this telegram in response to the Command 0x0005:
* GetCurrentPlayingTrackChapterPlayStatus telegram from the device.
* The returned information includes the chapter length and elapsed
* time, in milliseconds. If there is no currently playing chapter,
* the chapter length and elapsed time are zero.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0B Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x06 Command ID (bits 7:0)
* 6 0xNN Chapter length in milliseconds (bits 31:24)
* 7 0xNN Chapter length in milliseconds (bits 23:16)
* 8 0xNN Chapter length in milliseconds (bits 15:8)
* 9 0xNN Chapter length in milliseconds (bits 7:0)
* 10 0xNN Elapsed time in chapter, in milliseconds (bits 31:24)
* 11 0xNN Elapsed time in chapter, in milliseconds (bits 23:16)
* 12 0xNN Elapsed time in chapter, in milliseconds (bits 15:8)
* 13 0xNN Elapsed time in chapter, in milliseconds (bits 7:0)
* 14 0xNN Telegram payload checksum byte
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0007: /* GetCurrentPlayingTrackChapterName */
/* The following is the description for the Apple Firmware
*
* Requests a chapter name in the currently playing track. In
* response to a valid telegram, the iPod sends a Command 0x0008:
* ReturnCurrentPlayingTrackChapterName telegram to the device.
*
* Note: If the received telegram length or track index is invalid
* for instance, if the track does not have chapter information or
* is not a part of the Audiobook category, the iPod responds with
* an ACK telegram including the specific error status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x07 Command ID (bits 7:0)
* 6 0xNN Chapter index (bits 31:24)
* 7 0xNN Chapter index (bits 23:16)
* 8 0xNN Chapter index (bits 15:8)
* 9 0xNN Chapter index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
* We don't do anything with this as we don't support chapters,
* so just return BAD_PARAM
*/
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0008: /* ReturnCurrentPlayingTrackChapterName. See Above */
/* The following is the description for the Apple Firmware
*
* Returns a chapter name in the currently playing track. The iPod
* sends this telegram in response to a valid Command 0x0007:
* GetCurrentPlayingTrackChapterName telegram from the
* device. The chapter name is encoded as a null-terminated UTF-8
* character array.
*
* Note: The chapter name string is not limited to 252 characters;
* it may be sent in small or large telegram format depending on
* the string length. The small telegram format is shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x08 Command ID (bits 7:0)
* 6-N 0xNN Chapter name as UTF-8 character array
*(last byte) 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0009: /* GetAudioBookSpeed */
/* The following is the description for the Apple Firmware
*
* Requests the current iPod audiobook speed state. The iPod
* responds with the <20>Command 0x000A: ReturnAudiobookSpeed<65>
* telegram indicating the current audiobook speed.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x09 Command ID (bits 7:0)
* 6 0xF0 Telegram payload checksum byte
*
* ReturnAudioBookSpeed
* 0x00 = Normal, 0xFF = Slow, 0x01 = Fast
* We always respond with Normal speed
*/
{
unsigned char data[] = {0x04, 0x00, 0x0A, 0x00};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x000A: /* ReturnAudioBookSpeed. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the current audiobook speed setting. The iPod sends
* this telegram in response to the Command 0x0009:
* GetAudiobookSpeed command from the device.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0A Command ID (bits 7:0)
* 6 0xNN Audiobook speed status code.
* 0xFF Slow (-1)
* 0x00 Normal
* 0x01 Fast (+1)
* 7 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x000B: /* SetAudioBookSpeed */
/* The following is the description for the Apple Firmware
* Sets the speed of audiobook playback. The iPod audiobook speed
* states are listed above. This telegram has two modes: one to
* set the speed of the currently playing audiobook and a second
* to set the audiobook speed for all audiobooks. Byte number 7
* is an optional byte; devices should not send this byte if they
* want to set the speed only of the currently playing audiobook.
* If devices want to set the global audiobook speed setting then
* they must use byte number 7. This is the Restore on Exit byte;
* a nonzero value restores the original audiobook speed setting
* when the accessory is detached. If this byte is zero, the
* audiobook speed setting set by the accessory is saved and
* persists after the accessory is detached from the iPod. See below
* for the telegram format used when including the Restore on Exit
* byte.
* In response to this command, the iPod sends an ACK telegram with
* the command status.
*
* Note: Accessory developers are encouraged to always use the
* Restore on Exit byte with a nonzero value, to restore any of the
* user's iPod settings that were modified by the accessory.
*
* Byte Value Meaning (Cuurent audiobook only
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0B Command ID (bits 7:0)
* 6 0xNN New audiobook speed code.
* 7 0xNN Telegram payload checksum byte
*
*
* SetAudiobookSpeed telegram to set the global audiobook speed
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x05 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0B Command ID (bits 7:0)
* 6 0xNN Global audiobook speed code.
* 7 0xNN Restore on Exit byte.
* If 1, the original setting is restored on detach;
* if 0, the newsetting persists after accessory detach.
* 8 0xNN Telegram payload checksum byte
*
*
* We don't do anything with this as we don't support chapters,
* so just return BAD_PARAM
*/
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x000C: /* GetIndexedPlayingTrackInfo */
/* The following is the description for the Apple Firmware
*
* Gets track information for the track at the specified index.
* The track info type field specifies the type of information to be
* returned, such as song lyrics, podcast name, episode date, and
* episode description. In response, the iPod sends the Command
* 0x000D: ReturnIndexedPlayingTrackInfo command with the requested
* track information. If the information type is invalid or does not
* apply to the selected track, the iPod returns an ACK with an
* error status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0A Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0C Command ID (bits 7:0)
* 6 0xNN Track info type. See Below
* 7 0xNN Track index (bits 31:24)
* 8 0xNN Track index (bits 23:16)
* 9 0xNN Track index (bits 15:8)
* 10 0xNN Track index (bits 7:0)
* 11 0xNN Chapter index (bits 15:8)
* 12 0xNN Chapter index (bits 7:0)
* (last byte)0xNN Telegram payload checksum byte
*
* Track Info Types: Return Data
* 0x00 Track Capabilities. 10byte data
* 0x01 Podcast Name UTF-8 String
* 0x02 Track Release Date 7Byte Data All 0 if invalid
* 0x03 Track Description UTF-8 String
* 0x04 Track Song Lyrics UTF-8 String
* 0x05 Track Genre UTF-8 String
* 0x06 Track Composer UTF-8 String
* 0x07 Track Artwork Count 2byte formatID and 2byte count of images
* 0x08-0xff Reserved
*
* Track capabilities
* 0x00-0x03
* Bit0 is Audiobook
* Bit1 has chapters
* Bit2 has album art
* Bit3 has lyrics
* Bit4 is podcast episode
* Bit5 has Release Date
* Bit6 has Decription
* Bit7 Contains Video
* Bit8 Play as Video
* Bit9+ Reserved
* 0x04-0x07 Total Track Length in ms
* 0x08-0x09 Chapter Count
*
* Track Release Date Encoding
* 0x00 Seconds 0-59
* 0x01 Minutes 0-59
* 0x02 Hours 0-23
* 0x03 Day Of Month 1-31
* 0x04 Month 1-12
* 0x05 Year Bits 15:8 2006 = 2006AD
* 0x06 Year Bits 7:0
* 0x07 Weekday 0-6 where 0=Sunday 6=Saturday
*
*
*/
{
if (len < (10))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
struct mp3entry *id3 = audio_current_track();
switch(buf[3])
{
case 0x01: /* Podcast Not Supported */
case 0x04: /* Lyrics Not Supported */
case 0x03: /* Description */
case 0x05: /* Genre */
case 0x06: /* Composer */
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
default:
{
IAP_TX_INIT4(0x04, 0x000D);
IAP_TX_PUT(buf[3]);
switch(buf[3])
{
case 0x00:
{
/* Track Capabilities 10Bytes Data */
IAP_TX_PUT_U32(0); /* Track Capabilities. */
/* Currently None Supported*/
IAP_TX_PUT_U32(id3->length); /* Track Length */
IAP_TX_PUT_U16(0x00); /* Chapter Count */
break;
}
case 0x02:
{
/* Track Release Date 7 Bytes Data
* Currently only returns a fixed value,
* Sunday 1st Feb 2011 3Hr 4Min 5Secs
*/
IAP_TX_PUT(5); /* Seconds 0-59 */
IAP_TX_PUT(4); /* Minutes 0-59 */
IAP_TX_PUT(3); /* Hours 0-23 */
IAP_TX_PUT(1); /* Day Of Month 1-31 */
IAP_TX_PUT(2); /* Month 1-12 */
IAP_TX_PUT_U16(2011); /* Year */
IAP_TX_PUT(0); /* Day 0=Sunday */
break;
}
case 0x07:
{
/* Track Artwork Count */
/* Currently not supported */
IAP_TX_PUT_U16(0x00); /* Format ID */
IAP_TX_PUT_U16(0x00); /* Image Count */
break;
}
}
iap_send_tx();
break;
}
}
break;
}
case 0x000D: /* ReturnIndexedPlayingTrackInfo. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the requested track information type and data. The iPod
* sends this command in response to the Command 0x000C:
* GetIndexedPlayingTrackInfo command.
* Data returned as strings are encoded as null-terminated UTF-8
* character arrays.
* If the track information string does not exist, a null UTF-8
* string is returned. If the track has no release date, then the
* returned release date has all bytes zeros. Track song lyrics and
* the track description are sent in a large or small telegram
* format with an incrementing packet index field, spanning
* multiple packets if needed.
*
* Below is the packet format for the
* ReturnIndexedPlayingTrackInfo telegram sent in response to a
* request for information types 0x00 to 0x02.
*
* Byte Value Meaning
* 0 0xFF Sync byte
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0D Command ID (bits 7:0)
* 6 0xNN Track info type. See
* 7-N 0xNN Track information. The data format is specific
* to the track info type.
* NN 0xNN Telegram payload checksum byte
*
* Below is the large packet format for the
* ReturnIndexedPlayingTrackInfo telegram sent in response to a
* request for information types 0x03 to 0x04. The small telegram
* format is not shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte
* 1 0x55 Start of telegram
* 2 0x00 Telegram payload marker (large format)
* 3 0xNN Large telegram payload length (bits 15:8)
* 4 0xNN Large telegram payload length (bits 7:0)
* 5 0x04 Lingo ID (Extended Interface lingo)
* 6 0x00 Command ID (bits 15:8)
* 7 0x0D Command ID (bits 7:0)
* 8 0xNN Track info type.
* 9 0xNN Packet information bits. If set,
* these bits have the following meanings:
* Bit 0: Indicates that there are multiple packets.
* Bit 1: This is the last packet. Applicable only if
* bit 0 is set.
* Bit 31:2 Reserved
* 10 0xNN Packet Index (bits 15:8)
* 11 0xNN Packet Index (bits 7:0)
* 12-N 0xNN Track information as a UTF-8 string.
* NN 0xNN Telegram payload checksum byte
*
* Track info types and return data
* Info Type Code Data Format
* 0x00 Track Capabilities and Information 10-byte data.
* 0x01 PodcastName UTF-8 string
* 0x02 Track Release Date 7-byte data.
* 0x03 Track Description UTF-8 string
* 0x04 Track Song Lyrics UTF-8 string
* 0x05 TrackGenre UTF-8 string
* 0x06 Track Composer UTF-8 string
* 0x07 Track Artwork Count Artwork count data. The
* artwork count is a sequence of 4-byte records; each record
* consists of a 2-byte format ID value followed by a 2-byte
* count of images in that format for this track. For more
* information about formatID and chapter index values, see
* commands 0x000E-0x0011 and 0x002A-0x002B.
* 0x08-0xFF Reserved
*
* Track Capabilities and Information encoding
* Byte Code
* 0x00-0x03 Track Capability bits. If set, these bits have the
* following meanings:
* Bit 0: Track is audiobook
* Bit 1: Track has chapters
* Bit 2: Track has album artwork
* Bit 3: Track has song lyrics
* Bit 4: Track is a podcast episode
* Bit 5: Track has release date
* Bit 6: Track has description
* Bit 7: Track contains video (a video podcast, music
* video, movie, or TV show)
* Bit 8: Track is currently queued to play as a video
* Bit 31:9: Reserved
* 0x04 Total track length, in milliseconds (bits 31:24)
* 0x05 Total track length, in milliseconds (bits 23:16)
* 0x06 Total track length, in milliseconds (bits 15:8)
* 0x07 Total track length, in milliseconds (bits 7:0)
* 0x08 Chapter count (bits 15:8)
* 0x09 Chapter count (bits 7:0)
*
* Track Release Date encoding
* Byte Code
* 0x00 Seconds (0-59)
* 0x01 Minutes (0-59)
* 0x02 Hours (0-23)
* 0x03 Day of themonth(1-31)
* 0x04 Month (1-12)
* 0x05 Year (bits 15:8). For example, 2006 signifies the year 2006
* 0x06 Year (bits 7:0)
* 0x07 Weekday (0-6, where 0 = Sunday and 6 = Saturday)
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x000E: /* GetArtworkFormats */
/* The following is the description for the Apple Firmware
*
* The device sends this command to obtain the list of supported
* artwork formats on the iPod. No parameters are sent.
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0E Command ID (bits 7:0)
* 6 0xEB Checksum/
*
* Returned Artwork Formats are a 7byte record.
* formatID:2
* pixelFormat:1
* width:2
* height:2
*/
{
unsigned char data[] = {0x04, 0x00, 0x0F,
0x04, 0x04, /* FormatID */
0x02, /* PixelFormat*/
0x00, 0x64, /* 100 pixels */
0x00, 0x64, /* 100 pixels */
0x04, 0x05, /* FormatID */
0x02, /* PixelFormat*/
0x00, 0xC8, /* 200 pixels */
0x00, 0xC8 /* 200 pixels */
};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x000F: /* RetArtworkFormats. See Above */
/* The following is the description for the Apple Firmware
*
* The iPod sends this command to the device, giving it the list
* of supported artwork formats. Each format is described in a
* 7-byte record (formatID:2, pixelFormat:1, width:2, height:2).
* The formatID is used when sending GetTrackArtworkTimes.
* The device may return zero records.
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x0F Command ID (bits 7:0)
* NN 0xNN formatID (15:8) iPod-assigned value for this format
* NN 0xNN formatID (7:0)
* NN 0xNN pixelFormat. Same as from SetDisplayImage
* NN 0xNN imageWidth(15:8).Number of pixels widefor eachimage.
* NN 0xNN imageWidth (7:0)
* NN 0xNN imageHeight (15:8). Number of pixels high for each
* NN 0xNN imageHeight (7:0). image
* Previous 7 bytes may be repeated NN times
* NN 0xNN Checksum
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0010: /* GetTrackArtworkData */
/* The following is the description for the Apple Firmware
* The device sends this command to the iPod to request data for a
* given trackIndex, formatID, and artworkIndex. The time offset
* from track start is the value returned by GetTrackArtworkTimes
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0D Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x10 Command ID (bits 7:0)
* 6 0xNN trackIndex (31:24).
* 7 0xNN trackIndex(23:16)
* 8 0xNN trackIndex (15:8)
* 9 0xNN trackIndex (7:0)
* 10 0xNN formatID (15:8)
* 11 0xNN formatID (7:0)
* 12 0xNN time offset from track start, in ms (31:24)
* 13 0xNN time offset from track start, in ms (23:16)
* 14 0xNN time offset from track start, in ms (15:8)
* 15 0xNN time offset from track start, in ms (7:0)
* 16 0xNN Checksum
*
* Returned data is
* DescriptorTelegramIndex: 2
* pixelformatcode: 1
* ImageWidthPixels: 2
* ImageHeightPixels: 2
* InsetRectangleTopLeftX: 2
* InsetRectangleTopLeftY: 2
* InsetRectangleBotRightX: 2
* InsetRectangleBotRightY: 2
* RowSizeInBytes: 4
* ImagePixelData:VariableLength
* Subsequent packets omit bytes 8 - 24
*/
{
unsigned char data[] = {0x04, 0x00, 0x11,
0x00, 0x00, /* DescriptorIndex */
0x00, /* PixelFormat */
0x00, 0x00, /* ImageWidthPixels*/
0x00, 0x00, /* ImageHeightPixels*/
0x00, 0x00, /* InsetRectangleTopLeftX*/
0x00, 0x00, /* InsetRectangleTopLeftY*/
0x00, 0x00, /* InsetRectangleBotRightX*/
0x00, 0x00, /* InsetRectangleBotRoghtY*/
0x00, 0x00, 0x00, 0x00,/* RowSize*/
0x00 /* ImagePixelData Var Length*/
};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0011: /* RetTrackArtworkData. See Abobe */
/* The following is the description for the Apple Firmware
*
* The iPod sends the requested artwork to the accessory. Multiple
* RetTrackArtworkData commands may be necessary to transfer all
* the data because it will be too much to fit into a single packet.
* This command uses nearly the same format as the SetDisplayImage
* command (command 0x0032). The only difference is the addition
* of 2 coordinates; they define an inset rectangle that describes
* any padding that may have been added to the image. The
* coordinates consist of two x,y pairs. Each x or y value is 2
* bytes, so the total size of the coordinate set is 8 bytes.
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x11 Command ID (bits 7:0)
* 6 0x00 Descriptor telegram index (15:8).
* These fields uniquely identify each packet in the
* RetTrackArtworkData transaction. The first telegram
* is the descriptor telegram, which always starts with
* an index of 0x0000.
* 7 0x00 Descriptor telegram index (7:0)
* 8 0xNN Display pixel format code.
* 9 0xNN Imagewidth in pixels (15:8)
* 10 0xNN Image width in pixels (7:0)
* 11 0xNN Image height in pixels (15:8)
* 12 0xNN Image height in pixels (7:0)
* 13 0xNN Inset rectangle, top-left point, x value (15:8)
* 14 0xNN Inset rectangle, top-left point, x value (7:0)
* 15 0xNN Inset rectangle, top-left point, y value (15:8)
* 16 0xNN Inset rectangle, top-left point, y value (7:0)
* 17 0xNN Inset rectangle,bottom-rightpoint,xvalue(15:8)
* 18 0xNN Inset rectangle,bottom-rightpoint, x value(7:0)
* 19 0xNN Inset rectangle,bottom-rightpoint,y value(15:8)
* 20 0xNN Inset rectangle, bottom-right point, y value(7:0)
* 21 0xNN Rowsize in bytes (31:24)
* 22 0xNN Rowsize in bytes (23:16)
* 23 0xNN Row size in bytes (15:8)
* 24 0xNN Row size in bytes (7:0)
* 25-NN 0xNN Image pixel data (variable length)
* NN 0xNN Checksum
*
* In subsequent packets in the sequence, bytes 8 through 24 are
* omitted.
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0012: /* RequestProtocolVersion */
/* The following is the description for the Apple Firmware
*
* This command is deprecated.
*
* Requests the version of the running protocol from the iPod.
* The iPod responds with a Command 0x0013:ReturnProtocolVersion
* command.
*
* Note: This command requests the Extended Interface protocol
* version, not the iPod software version.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x12 Command ID (bits 7:0)
* 6 0xE7 Telegram payload checksum byte
*
*/
{
IAP_TX_INIT4(0x04, 0x0013);
IAP_TX_PUT(LINGO_MAJOR(0x04));
IAP_TX_PUT(LINGO_MINOR(0x04));
iap_send_tx();
break;
}
case 0x0013: /* ReturnProtocolVersion. See Above */
/* The following is the description for the Apple Firmware
* This command is deprecated.
* Sent from the iPod to the device
* Returns the iPod Extended Interface protocol version number.
* The iPod sends this command in response to the Command 0x0012:
* RequestProtocolVersion command from the device. The major
* version number specifies the protocol version digits to the left
* of the decimal point; the minor version number specifies the
* digits to the right of the decimal point. For example, a major
* version number of 0x01 and a minor version number of 0x08
* represents an Extended Interface protocol version of 1.08. This
* protocol information is also available through the General lingo
* (lingo 0x00) command RequestLingoProtocolVersion when passing
* lingo 0x04 as the lingo parameter.
*
* Note: This command returns the Extended Interface protocol
* version, not the iPod software version.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x05 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x13 Command ID (bits 7:0)
* 6 0xNN Protocol major version number
* 7 0xNN Protocol minor version number
* 8 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0014: /* RequestiPodName */
/* The following is the description for the Apple Firmware
* This command is deprecated.
* Retrieves the name of the iPod
*
* Returns the name of the user's iPod or 'iPod' if the iPod name
* is undefined. This allows the iPod name to be shown in the
* human-machineinterface(HMI) of the interfacingbody. The iPod
* responds with the Command 0x0015: ReturniPodName command
* containing the iPod name text string.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x14 Command ID (bits 7:0)
* 6 0xE5 Telegram payload checksum byte
*
* We return ROCKBOX, should this be definable?
* Should it be Volume Name?
*/
{
IAP_TX_INIT4(0x04, 0x0015);
IAP_TX_PUT_STRING("ROCKBOX");
iap_send_tx();
break;
}
case 0x0015: /* ReturniPodName. See Above */
/* The following is the description for the Apple Firmware
* This command is deprecated.
* Sent from the iPod to the device
*
* The iPod sends this command in response to the Command 0x0014:
* RequestiPodName telegram from the device. The iPod name is
* encoded as a null-terminated UTF-8 character array. The iPod
* name string is not limited to 252 characters; it may be sent
* in small or large telegram format. The small telegram format
* is shown.
*
* Note: Starting with version 1.07 of the Extended Interface lingo,
* the ReturniPodName command on Windows-formatted iPods returns the
* iTunes name of the iPod instead of the Windows volume name.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x15 Command ID (bits 7:0)
* 6-N 0xNN iPod name as UTF-8 character array
* NN 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0016: /* ResetDBSelection */
/* The following is the description for the Apple Firmware
*
* Resets the current database selection to an empty state and
* invalidates the category entry count that is, sets the count
* to 0, for all categories except the playlist category. This is
* analogous to pressing the Menu button repeatedly to get to the
* topmost iPod HMI menu. Any previously selected database items
* are deselected. The command has no effect on the playback engine
* In response, the iPod sends an ACK telegram with the command
* status. Once the accessory has reset the database selection,
* it must initialize the category count before it can select
* database records. Please refer to Command 0x0018:
* GetNumberCategorizedDBRecords and Command 0x0017:
* SelectDBRecord for details.
*
* Note: Starting with protocol version 1.07, the ResetDBSelection
* command clears the sort order.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x16 Command ID (bits 7:0)
* 6 0xE3 Telegram payload checksum byte
*
*
* Reset the DB Record Type
* Hierarchy is as follows
* All = 0
* Playlist = 1
* Artist = 2
* Album = 3
* Genre = 4
* Tracks = 5
* Composers = 6
* Audiobooks = 7
* Podcasts = 8
*
*/
{
cur_dbrecord[0] = 0;
put_u32(&cur_dbrecord[1],0);
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0017: /* SelectDBRecord */
/* The following is the description for the Apple Firmware
* Selects one or more records in the Database Engine, based on a
* category relative index. For example, selecting category two
* (artist) and record index one results in a list of selected
* tracks (or database records) from the second artist in the
* artist list.
* Selections are additive and limited by the category hierarchy;
* Subsequent selections are made based on the subset of records
* resulting from the previous selections and not from the entire
* database.
* Note that the selection of a single record automatically passes
* it to the Playback Engine and starts its playback. Record indices
* consist of a 32-bit signed integer. To select database records
* with a specific sort order, use
* Command 0x0038: SelectSortDBRecord
* SelectDBRecord should be called only once a category count has
* been initialized through a call to Command 0x0018:
* GetNumberCategorizedDBRecords. Without a valid category count,
* the SelectDBRecord call cannot select a database record and will
* fail with a command failed ACK. Accessories that make use of
* Command 0x0016: ResetDBSelection must always initialize the
* category count before selecting a new database record using
* SelectDBRecord.
* Accessories should pay close attention to the ACK returned by the
* SelectDBRecord command. Ignoring errors may cause unexpected
* behavior.
* To undo a database selection, send the SelectDBRecord telegram
* with the current category selected in theDatabase Engine and a
* record index of -1 (0xFFFFFFFF). This has the same effect as
* pressing the iPod Menu button once and moves the database
* selection up to the next highest menu level. For example, if a
* device selected artist number three and then album number one,
* it could use the SelectDBRecord(Album, -1) telegram to return
* to the database selection of artist number three. If multiple
* database selections have been made, devices can use any of the
* previously used categories to return to the next highest database
* selection. If the category used in one of these SelectDBRecord
* telegrams has not been used in a previous database selection
* then the command is treated as a no-op.
* Sending a SelectDBRecord telegram with the Track category and a
* record index of -1 is invalid, because the previous database
* selection made with the Track category and a valid index passes
* the database selection to the Playback Engine.
* Sending a SelectDBRecord(Track, -1) telegram returns a parameter
* error. The iPod also returns a bad parameter error ACK when
* devices send the SelectDBRecord telegram with an invalid category
* type, or with the Track category and an index greater than the
* total number of tracks available on the iPod.
*
* Note: Selecting a podcast always selects from the main podcast
* library regardless of the current category context of the iPod.
*
* To immediately go to the topmost iPod menu level and reset all
* database selections, send the ResetDBSelection telegram to the
* iPod.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x08 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x17 Command ID (bits 7:0)
* 6 0xNN Database category type. See
* 7 0xNN Database record index (bits 31:24)
* 8 0xNN Database record index (bits 23:16)
* 9 0xNN Database record index (bits 15:8)
* 10 0xNN Database record index (bits 7:0)
* 11 0xNN Telegram payload checksum byte
*
* The valid database categories are listed below
*
* Category Code Protocol version
* Reserved 0x00 N/A
* Playlist 0x01 1.00
* Artist 0x02 1.00
* Album 0x03 1.00
* Genre 0x04 1.00
* Track 0x05 1.00
* Composer 0x06 1.00
* Audiobook0x07 1.06
* Podcast 0x08 1.08
* Reserved 0x09+ N/A
*
* cur_dbrecord[0] is the record type
* cur_dbrecord[1-4] is the u32 of the record number requested
* which might be a playlist or a track number depending on
* the value of cur_dbrecord[0]
*/
{
memcpy(cur_dbrecord, buf + 3, 5);
int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
uint32_t index;
uint32_t trackcount;
index = get_u32(&cur_dbrecord[1]);
trackcount = playlist_amount();
if ((cur_dbrecord[0] == 5) && (index > trackcount))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
if ((cur_dbrecord[0] == 1) && (index > (nbr_total_playlists() + 1)))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
audio_pause();
switch (cur_dbrecord[0])
{
case 0x01: /* Playlist*/
{
if (index != 0x00) /* 0x00 is the On-The-Go Playlist and
we do nothing with it */
{
last_selected_playlist = index;
audio_skip(-iap_get_trackindex());
seek_to_playlist(last_selected_playlist);
}
break;
}
case 0x02: /* Artist */
case 0x03: /* Album */
case 0x04: /* Genre */
case 0x05: /* Track */
case 0x06: /* Composer */
{
audio_skip(index - playlist_next(0));
break;
}
default:
{
/* We don't do anything with the other selections.
* YET.
*/
break;
}
}
if (!paused)
audio_resume();
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0018: /* GetNumberCategorizedDBRecords */
/* The following is the description for the Apple Firmware
*
* Retrieves the number of records in a particular database
* category.
* For example, a device can get the number of artists or albums
* present in the database. The category types are described above.
* The iPod responds with a Command 0x0019:
* ReturnNumberCategorizedDBRecords telegram indicating the number
* of records present for this category.
* GetNumberCategorizedDBRecords must be called to initialize the
* category count before selecting a database record using Command
* 0x0017: SelectDBRecord or Command 0x0038: SelectSortDBRecord
* commands. A category<72>s record count can change based on the prior
* categories selected and the database hierarchy. The accessory
* is expected to call GetNumberCategorizedDBRecords in order to
* get the valid range of category entries before selecting a
* record in that category.
*
* Note: The record count returned by this command depends on the
* database state before this command is sent. If the database has
* been reset using Command 0x0016: ResetDBSelection this command
* returns the total number of records for a given category.
* However, if this command is sent after one or more categories
* are selected, the record count is the subset of records that are
* members of all the categories selected prior to this command.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x18 Command ID (bits 7:0)
* 6 0xNN Database category type. See above
* 7 0xNN Telegram payload checksum byte
*
* This is the actual number of available records for that category
* some head units (Alpine CDE-103BT) use this command before
* requesting records and then hang if not enough records are
* returned.
*/
{
unsigned char data[] = {0x04, 0x00, 0x19,
0x00, 0x00, 0x00, 0x00};
switch(buf[3]) /* type number */
{
case 0x01: /* total number of playlists */
dbrecordcount = nbr_total_playlists() + 1;
break;
case 0x05: /* total number of Tracks */
case 0x02: /* total number of Artists */
case 0x03: /* total number of Albums */
/* We don't sort on the above but some Head Units
* require at least one to exist so we just return
* the number of tracks in the playlist. */
dbrecordcount = playlist_amount();
break;
case 0x04: /* total number of Genres */
case 0x06: /* total number of Composers */
case 0x07: /* total number of AudioBooks */
case 0x08: /* total number of Podcasts */
/* We don't support the above so just return that
there are none available. */
dbrecordcount = 0;
break;
}
put_u32(&data[3], dbrecordcount);
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0019: /* ReturnNumberCategorizedDBRecords. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the number of database records matching the specified
* database category. The iPod sends this telegram in response to
* the Command 0x0018: GetNumberCategorizedDBRecords telegram from
* the device. Individual records can then be extracted by sending
* Command 0x001A: RetrieveCategorizedDatabaseRecords to the iPod.
* If no matching database records are found, a record count of
* zero is returned. Category types are described above.
* After selecting the podcast category, the number of artist,
* album, composer, genre, and audiobook records is always zero.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x19 Command ID (bits 7:0)
* 6 0xNN Database record count (bits 31:24)
* 7 0xNN Database record count (bits 23:16)
* 8 0xNN Database record count (bits 15:8)
* 9 0xNN Database record count (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x001A: /* RetrieveCategorizedDatabaseRecords */
/* The following is the description for the Apple Firmware
*
* Retrieves one or more database records from the iPod,
* typically based on the results from the Command 0x0018:
* GetNumberCategorizedDBRecords query. The database
* category types are described above. This telegram
* specifies the starting record index and the number of
* records to retrieve (the record count). This allows a device
* to retrieve an individual record or the entire set of records
* for a category. The record start index and record count consist
* of 32-bit signed integers. To retrieve all records from a given
* starting record index, set the record count to -1 (0xFFFFFFFF).
* The iPod responds to this telegram with a separate Command
* 0x001B: ReturnCategorizedDatabaseRecord telegram FOR EACH record
* matching the specified criteria (category and record index
* range).
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0C Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1A Command ID (bits 7:0)
* 6 0xNN Database category type. See above
* 7 0xNN Database record start index (bits 31:24)
* 8 0xNN Database record start index (bits 23:16)
* 9 0xNN Database record start index (bits 15:8)
* 10 0xNN Database record start index (bits 7:0)
* 11 0xNN Database record read count (bits 31:24)
* 12 0xNN Database record read count (bits 23:16)
* 13 0xNN Database record read count (bits 15:8)
* 14 0xNN Database record read count (bits 7:0)
* 15 0xNN Telegram payload checksum byte
* The returned data
* contains information for a single database record. The iPod sends
* one or more of these telegrams in response to the Command 0x001A:
* RetrieveCategorizedDatabaseRecords telegram from the device. The
* category record index is included to allow the device to
* determine which record has been sent. The record data is sent as
* a null-terminated UTF-8 encoded data array.
*/
{
unsigned char data[7 + MAX_PATH] =
{0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00,
'O','n','-','T','h','e','-','G','o','\0'};
struct playlist_track_info track;
struct mp3entry id3;
unsigned long start_index = get_u32(&buf[4]);
unsigned long read_count = get_u32(&buf[8]);
unsigned long counter = 0;
unsigned int number_of_playlists = nbr_total_playlists();
uint32_t trackcount;
trackcount = playlist_amount();
if ((buf[3] == 0x05) && ((start_index + read_count ) > trackcount))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
if ((buf[3] == 0x01) && ((start_index + read_count) > (number_of_playlists + 1)))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
for (counter=0;counter<read_count;counter++)
{
switch(buf[3]) /* type number */
{
case 0x01: /* Playlists */
get_playlist_name(data +7,start_index+counter, MAX_PATH);
/*Remove file extension*/
char *dot=NULL;
dot = (strrchr(data+7, '.'));
if (dot != NULL)
*dot = '\0';
break;
case 0x05: /* Tracks */
case 0x02: /* Artists */
case 0x03: /* Albums */
case 0x04: /* Genre */
case 0x06: /* Composer */
playlist_get_track_info(NULL, start_index + counter,
&track);
iap_get_trackinfo(start_index + counter, &id3);
switch(buf[3])
{
case 0x05:
strmemccpy((char *)&data[7], id3.title,64);
break;
case 0x02:
strmemccpy((char *)&data[7], id3.artist,64);
break;
case 0x03:
strmemccpy((char *)&data[7], id3.album,64);
break;
case 0x04:
case 0x06:
strmemccpy((char *)&data[7], "Not Supported",14);
break;
}
break;
}
put_u32(&data[3], start_index+counter);
iap_send_pkt(data, 7 + strlen(data+7) + 1);
yield();
}
break;
}
case 0x001B: /* ReturnCategorizedDatabaseRecord. See Above */
/* The following is the description for the Apple Firmware
*
* Contains information for a single database record. The iPod sends
* ONE OR MORE of these telegrams in response to the Command 0x001A:
* RetrieveCategorizedDatabaseRecords telegram from the device. The
* category record index is included to allow the device to
* determine which record has been sent. The record data is sent
* as a null-terminated UTF-8 encoded data array.
*
* Note: The database record string is not limited to 252 characters
* it may be sent in small or large telegram format, depending on
* the record size. The small telegram format is shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1B Command ID (bits 7:0)
* 6 0xNN Database record category index (bits 31:24)
* 7 0xNN Database record category index (bits 23:16)
* 8 0xNN Database record category index (bits 15:8)
* 9 0xNN Database record category index (bits 7:0)
* 10-N 0xNN Database record as a UTF-8 character array.
* NN 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x001C: /* GetPlayStatus */
/* The following is the description for the Apple Firmware
*
* Requests the current iPod playback status, allowing the
* device to display feedback to the user. In response, the
* iPod sends a Command 0x001D: ReturnPlayStatus telegram
* with the current playback status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1C Command ID (bits 7:0)
* 6 0xDD Telegram payload checksum byte
*
*/
{
unsigned char data[] = {0x04, 0x00, 0x1D,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00};
struct mp3entry *id3 = audio_current_track();
unsigned long time_total = id3->length;
unsigned long time_elapsed = id3->elapsed;
int status = audio_status();
put_u32(&data[3], time_total);
put_u32(&data[7], time_elapsed);
if (status == AUDIO_STATUS_PLAY)
data[11] = 0x01; /* play */
else if (status & AUDIO_STATUS_PAUSE)
data[11] = 0x02; /* pause */
iap_send_pkt(data, sizeof(data));
break;
}
case 0x001D: /* ReturnPlayStatus. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the current iPod playback status. The iPod sends this
* telegram in response to the Command 0x001C: GetPlayStatus
* telegram from the device. The information returned includes the
* current track length, track position, and player state.
*
* Note: The track length and track position fields are valid only
* if the player state is Playing or Paused. For other player
* states, these fields should be ignored.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0C Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1D Command ID (bits 7:0)
* 6 0xNN Track length in milliseconds (bits 31:24)
* 7 0xNN Track length in milliseconds (bits 23:16)
* 8 0xNN Track length in milliseconds (bits 15:8)
* 9 0xNN Track length in milliseconds (bits 7:0)
* 10 0xNN Track position in milliseconds (bits 31:24)
* 11 0xNN Track position in milliseconds (bits 23:16)
* 12 0xNN Track position in milliseconds (bits 15:8)
* 13 0xNN Track position in milliseconds (bits 7:0)
* 14 0xNN Player state. Possible values are:
* 0x00 = Stopped
* 0x01 = Playing
* 0x02 = Paused
* 0x03 - 0xFE = Reserved
* 0xFF = Error
* 15 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x001E: /* GetCurrentPlayingTrackIndex */
/* The following is the description for the Apple Firmware
*
* Requests the playback engine index of the currently playing
* track. In response, the iPod sends a Command 0x001F:
* ReturnCurrentPlayingTrackIndex telegram to the device.
*
* Note: The track index returned is valid only if there is
* currently a track playing or paused.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1E Command ID (bits 7:0)
* 6 0xDB Telegram payload checksum byte
*
*/
{
unsigned char data[] = {0x04, 0x00, 0x1F,
0xFF, 0xFF, 0xFF, 0xFF};
long playlist_pos = playlist_next(0);
int status = audio_status();
playlist_pos -= playlist_get_first_index(NULL);
if(playlist_pos < 0)
playlist_pos += playlist_amount();
if ((status == AUDIO_STATUS_PLAY) || (status & AUDIO_STATUS_PAUSE))
put_u32(&data[3], playlist_pos);
iap_send_pkt(data, sizeof(data));
break;
}
case 0x001F: /* ReturnCurrentPlayingTrackIndex. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the playback engine index of the current playing track in
* response to the Command 0x001E: GetCurrentPlayingTrackIndex
* telegram from the device. The track index is a 32-bit signed
* integer.
* If there is no track currently playing or paused, an index of -1
* (0xFFFFFFFF) is returned.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x1F Command ID (bits 7:0)
* 6 0xNN Playback track index (bits 31:24)
* 7 0xNN Playback track index (bits 23:16)
* 8 0xNN Playback track index (bits 15:8)
* 9 0xNN Playback track index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0020: /* GetIndexedPlayingTrackTitle. See 0x0024 below */
/* The following is the description for the Apple Firmware
*
* Requests the title name of the indexed playing track from the
* iPod. In response to a valid telegram, the iPod sends a
* Command 0x0021: ReturnIndexedPlayingTrackTitle telegram to the
* device.
*
* Note: If the telegram length or playing track index is invalid,
* the iPod responds with an ACK telegram including the specific
* error status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x20 Command ID (bits 7:0)
* 6 0xNN Playback track index (bits 31:24)
* 7 0xNN Playback track index (bits 23:16)
* 8 0xNN Playback track index (bits 15:8)
* 9 0xNN Playback track index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
case 0x0021: /* ReturnIndexedPlayingTrackTitle. See 0x0024 Below */
/* The following is the description for the Apple Firmware
*
* Returns the title of the indexed playing track in response to
* a valid Command 0x0020 GetIndexedPlayingTrackTitle telegram from
* the device. The track title is encoded as a null-terminated UTF-8
* character array.
*
* Note: The track title string is not limited to 252 characters;
* it may be sent in small or large telegram format, depending on
* the string length. The small telegram format is shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x21 Command ID (bits 7:0)
* 6-N 0xNN Track title as a UTF-8 character array
* NN 0xNN Telegram payload checksum byte
*
*/
case 0x0022: /* GetIndexedPlayingTrackArtistName. See 0x0024 Below */
/* The following is the description for the Apple Firmware
*
* Requests the name of the artist of the indexed playing track
* In response to a valid telegram, the iPod sends a
* Command 0x0023: ReturnIndexedPlayingTrackArtistName telegram to
* the device.
*
* Note: If the telegram length or playing track index is invalid,
* the iPod responds with an ACK telegram including the specific
* error status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x22 Command ID (bits 7:0)
* 6 0xNN Playback track index (bits 31:24)
* 7 0xNN Playback track index (bits 23:16)
* 8 0xNN Playback track index (bits 15:8)
* 9 0xNN Playback track index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
case 0x0023: /* ReturnIndexedPlayingTrackArtistName. See 0x0024 Below */
/* The following is the description for the Apple Firmware
*
* Returns the artist name of the indexed playing track in response
* to a valid Command 0x0022 GetIndexedPlayingTrackArtistName
* telegram from the device. The track artist name is encoded as a
* null-terminated UTF-8 character array.
*
* Note: The artist name string is not limited to 252 characters;
* it may be sent in small or large telegram format, depending on
* the string length. The small telegram format is shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x23 Command ID (bits 7:0)
* 6-N 0xNN Track Artist as a UTF-8 character array
* NN 0xNN Telegram payload checksum byte
*
*/
case 0x0024: /* GetIndexedPlayingTrackAlbumName AND
* GetIndexedPlayingTrackTitle AND
* AND GetIndexedPlayingTrackArtistName. */
/* The following is the description for the Apple Firmware
*
* Requests the album name of the indexed playing track
* In response to a valid telegram, the iPod sends a
* Command 0x0025: ReturnIndexedPlayingTrackAlbumName telegram to
* the device.
*
* Note: If the telegram length or playing track index is invalid,
* the iPod responds with an ACK telegram including the specific
* error status.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x24 Command ID (bits 7:0)
* 6 0xNN Playback track index (bits 31:24)
* 7 0xNN Playback track index (bits 23:16)
* 8 0xNN Playback track index (bits 15:8)
* 9 0xNN Playback track index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
unsigned char data[70] = {0x04, 0x00, 0xFF};
struct mp3entry id3;
int fd;
size_t len;
long tracknum = get_u32(&buf[3]);
data[2] = cmd + 1;
memcpy(&id3, audio_current_track(), sizeof(id3));
tracknum += playlist_get_first_index(NULL);
if(tracknum >= playlist_amount())
tracknum -= playlist_amount();
/* If the tracknumber is not the current one,
read id3 from disk */
if(playlist_next(0) != tracknum)
{
struct playlist_track_info info;
playlist_get_track_info(NULL, tracknum, &info);
fd = open(info.filename, O_RDONLY);
memset(&id3, 0, sizeof(struct mp3entry));
get_metadata(&id3, fd, info.filename);
close(fd);
}
/* Return the requested track data */
switch(cmd)
{
case 0x20:
len = strlcpy((char *)&data[3], id3.title, 64);
iap_send_pkt(data, 4+len);
break;
case 0x22:
len = strlcpy((char *)&data[3], id3.artist, 64);
iap_send_pkt(data, 4+len);
break;
case 0x24:
len = strlcpy((char *)&data[3], id3.album, 64);
iap_send_pkt(data, 4+len);
break;
}
break;
}
case 0x0025: /* ReturnIndexedPlayingTrackAlbumName. See 0x0024 Above */
/* The following is the description for the Apple Firmware
*
* Returns the album name of the indexed playing track in response
* to a valid Command 0x0024 GetIndexedPlayingTrackAlbumName
* telegram from the device. The track artist name is encoded as a
* null-terminated UTF-8 character array.
*
* Note: The album name string is not limited to 252 characters;
* it may be sent in small or large telegram format, depending on
* the string length. The small telegram format is shown.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x25 Command ID (bits 7:0)
* 6-N 0xNN Track Album as a UTF-8 character array
* NN 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0026: /* SetPlayStatusChangeNotification */
/* The following is the description for the Apple Firmware
* Sets the state of play status change notifications from the iPod
* to the device. Notification of play status changes can be
* globally enabled or disabled. If notifications are enabled, the
* iPod sends a Command 0x0027: PlayStatusChangeNotification
* telegram to the device each time the play status changes, until
* the device sends this telegram again with the disable
* notification option. In response, the iPod sends an ACK telegram
* indicating the status of the SetPlayStatusChangeNotification
* command.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x26 Command ID (bits 7:0)
* 6 0xNN The state of play status change notifications.
* Possible values are:
* 0x00 = Disable all change notification
* 0x01 = Enable all change notification
* 0x02 - 0xFF = Reserved
* 7 0xNN Telegram payload checksum byte
*/
{
device.do_notify = buf[3] ? true : false;
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0027: /* PlayStatusChangeNotification */
/* This response is handled by iap_track_changed() and iap_periodic()
* within iap-core.c
* The following is the description for the Apple Firmware
*
* The iPod sends this telegram to the device when the iPod play status
* changes, if the device has previously enabled notifications using
* Command 0x0026: SetPlayStatusChangeNotification . This telegram
* contains details about the new play status. Notification telegrams
* for changes in track position occur approximately every 500
* milliseconds while the iPod is playing. Notification telegrams are
* sent from the iPod until the device sends the
* SetPlayStatusChangeNotification telegram with the option to disable
* all notifications.
* Some notifications include additional data about the new play status.
*
* PlayStatusChangeNotification telegram: notifications 0x00, 0x02, 0x03
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x27 Command ID (bits 7:0)
* 6 0xNN New play status. See Below.
* 7 0xNN Telegram payload checksum byte
*
* Play Status Change Code Extended Status Data (if
* any)
* Playback stopped 0x00 None
* Playback track changed 0x01 New track record index
* (32 bits)
* Playback forward seek stop 0x02 None
* Playback backward seek stop 0x03 None
* Playback track position 0x04 New track position in
* milliseconds (32 bits)
* Playback chapter changed 0x05 New chapter index (32
* bits)
* Reserved 0x06 - 0xFF N/A
*
* Playback track changed (code 0x01)
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x08 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x27 Command ID (bits 7:0)
* 6 0x01 New status: Playback track changed
* 7 0xNN New playback track index (bits 31:24)
* 8 0xNN New playback track index (bits 23:16)
* 9 0xNN New playback track index (bits 15:8)
* 10 0xNN New playback track index (bits 7:0)
* 11 0xNN Telegram payload checksum byte
*
* Playback track position changed (code 0x04)
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x08 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x27 Command ID (bits 7:0)
* 6 0x04 New status: Playback track position changed
* 7 0xNN New track position in milliseconds (bits 31:24)
* 8 0xNN New track position in milliseconds (bits 23:16)
* 9 0xNN New track position in milliseconds (bits 15:8)
* 10 0xNN New track position in milliseconds (bits 7:0)
* 11 0xNN Telegram payload checksum byte
*
* Playback chapter changed (code 0x05)
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x08 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x27 Command ID (bits 7:0)
* 6 0x05 New status: Playback chapter changed
* 7 0xNN New track chapter index (bits 31:24)
* 8 0xNN New track chapter index (bits 23:16)
* 9 0xNN New track chapter index (bits 15:8)
* 10 0xNN New track chapter index (bits 7:0)
* 11 0xNN Telegram payload checksum byte
*
*/
case 0x0028: /* PlayCurrentSelection */
/* The following is the description for the Apple Firmware
*
* Requests playback of the currently selected track or list of
* tracks. The currently selected tracks are placed in the Now
* Playing playlist, where they are optionally shuffled (if the
* shuffle feature is enabled). Finally, the specified track record
* index is passed to the player to play. Note that if the track
* index is -1(0xFFFFFFFF), the first track after the shuffle is
* complete is played first. If a track index of n is sent, the nth
* track of the selected tracks is played first, regardless of
* where it is located in the Now Playing playlist after the shuffle
* is performed (assuming that shuffle is on). In response, the iPod
* sends an ACK telegram indicating the status of the command.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x28 Command ID (bits 7:0)
* 6 0xNN Selection track record index (bits 31:24)
* 7 0xNN Selection track record index (bits 23:16)
* 8 0xNN Selection track record index (bits 15:8)
* 9 0xNN Selection track record index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
uint32_t index;
uint32_t trackcount;
index = get_u32(&buf[3]);
trackcount = playlist_amount();
if (index >= trackcount)
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
audio_pause();
if(global_settings.playlist_shuffle)
{
playlist_randomise(NULL, current_tick, true);
}
else
{
playlist_sort(NULL, true);
}
audio_skip(index - playlist_next(0));
if (!paused)
audio_resume();
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0029: /* PlayControl */
{
/* The following is the description for the Apple Firmware
*
* Sets the new play state of the iPod. The play control command
* codes are shown below. In response, the iPod sends an ACK
* telegram indicating the status of the command.
*
* Note: If a remote device requests the Next or Previous Chapter
* for a track that does not contain chapters, the iPod returns a
* command failed ACK.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x29 Command ID (bits 7:0)
* 6 0xNN Play control command code.
* 7 0xNN Telegram payload checksum byte
*
* Play Control Command Code Protocol version
* Reserved 0x00 N/A
* Toggle Play/Pause 0x01 1.00
* Stop 0x02 1.00
* Next Track 0x03 1.00
* Previous Track 0x04 1.00
* StartFF 0x05 1.00
* StartRew 0x06 1.00
* EndFFRew 0x07 1.00
* NextChapter 0x08 1.06
* Previous Chapter 0x09 1.06
* Reserved 0x0A - 0xFF
*
*/
switch(buf[3])
{
case 0x01: /* play/pause */
iap_remotebtn = BUTTON_RC_PLAY;
iap_repeatbtn = 2;
break;
case 0x02: /* stop */
iap_remotebtn = BUTTON_RC_PLAY|BUTTON_REPEAT;
iap_repeatbtn = 2;
break;
case 0x03: /* skip++ */
iap_remotebtn = BUTTON_RC_RIGHT;
iap_repeatbtn = 2;
break;
case 0x04: /* skip-- */
iap_remotebtn = BUTTON_RC_LEFT;
iap_repeatbtn = 2;
break;
case 0x05: /* ffwd */
iap_remotebtn = BUTTON_RC_RIGHT;
break;
case 0x06: /* frwd */
iap_remotebtn = BUTTON_RC_LEFT;
break;
case 0x07: /* end ffwd/frwd */
iap_remotebtn = BUTTON_NONE;
break;
}
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x002A: /* GetTrackArtworkTimes */
/* The following is the description for the Apple Firmware
*
* The device sends this command to the iPod to request the list of
* artwork time locations for a track. A 4-byte track Index
* specifies which track from the Playback Engine is to be selected.
* A 2-byte formatID indicates which type of artwork is desired.
* The 2-byte artworkIndex specifies at which index to begin
* searching for artwork. A value of 0 indicates that the iPod
* should start with the first available artwork.
* The 2-byte artworkCount specifies the maximum number of times
* (artwork locations) to be returned. A value of -1 (0xFFFF)
* indicates that there is no preferred limit. Note that podcasts
* may have a large number of associated images.
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x0D Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2A Command ID (bits 7:0)
* 6 0xNN trackIndex(31:24)
* 7 0xNN trackIndex(23:16)
* 8 0xNN trackIndex (15:8)
* 9 0xNN trackIndex (7:0)
* 10 0xNN formatID (15:8)
* 11 0xNN formatID (7:0)
* 12 0xNN artworkIndex (15:8)
* 13 0xNN artworkIndex (7:0)
* 14 0xNN artworkCount (15:8)
* 15 0xNN artworkCount (7:0)
* 16 0xNN Checksum
*
*/
{
unsigned char data[] = {0x04, 0x00, 0x2B,
0x00, 0x00, 0x00, 0x00};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x002B: /* ReturnTrackArtworkTimes. See Above */
/* The following is the description for the Apple Firmware
*
* The iPod sends this command to the device to return the list of
* artwork times for a given track. The iPod returns zero or more
* 4-byte times, one for each piece of artwork associated with the
* track and format specified by GetTrackArtworkTimes.
* The number of records returned will be no greater than the number
* specified in the GetTrackArtworkTimes command. It may however, be
* less than requested. This can happen if there are fewer pieces of
* artwork available than were requested, or if the iPod is unable
* to place the full number in a single packet. Check the number of
* records returned against the results of
* RetIndexedPlayingTrackInfo with infoType 7 to ensure that all
* artwork has been received.
*
* Byte Value Comment
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Length of packet
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2B Command ID (bits 7:0)
* 6 0xNN time offset from track start in ms (31:24)
* 7 0xNN time offset from track start in ms (23:16)
* 8 0xNN time offset from track start in ms (15:8)
* 9 0xNN time offset from track start in ms (7:0)
* Preceding 4 bytes may be repeated NN times
* NN 0xNN Checksum
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x002C: /* GetShuffle */
{
/* The following is the description for the Apple Firmware
*
* Requests the current state of the iPod shuffle setting. The iPod
* responds with the Command0x002D: ReturnShuffle telegram.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2C Command ID (bits 7:0)
* 6 0xCD Telegram payload checksum byte
*
*/
unsigned char data[] = {0x04, 0x00, 0x2D,
0x00};
data[3] = global_settings.playlist_shuffle ? 1 : 0;
iap_send_pkt(data, sizeof(data));
break;
}
case 0x002D: /* ReturnShuffle. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the current state of the shuffle setting. The iPod sends
* this telegram in response to the Command 0x002C: GetShuffle
* telegram from the device.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2D Command ID (bits 7:0)
* 6 0xNN Shuffle mode. See Below.
* 7 0xNN Telegram payload checksum byte
*
* Possible values of the shufflemode.
* Value Meaning
* 0x00 Shuffle off
* 0x01 Shuffle tracks
* 0x02 Shuffle albums
* 0x03 <20> 0xFF Reserved
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x002E: /* SetShuffle */
{
/* The following is the description for the Apple Firmware
*
* Sets the iPod shuffle mode. The iPod shuffle modes are listed
* below. In response, the iPod sends an ACK telegram with the
* command status.
* This telegram has an optional byte, byte 0x07, called the
* RestoreonExit byte. This byte can be used to restore the
* original shuffle setting in use when the accessory was attached
* to the iPod. A non zero value restores the original shuffle
* setting of the iPod when the accessory is detached. If this byte
* is zero, the shuffle setting set by the accessory overwrites the
* original setting and persists after the accessory is detached
* from the iPod.
* Accessory engineers should note that the shuffle mode affects
* items only in the playback engine. The shuffle setting does not
* affect the order of tracks in the database engine, so calling
* Command 0x001A: RetrieveCategorizedDatabaseRecords on a database
* selection with the shuffle mode set returns a list of unshuffled
* tracks. To get the shuffled playlist, an accessory must query the
* playback engine by calling Command 0x0020
* GetIndexedPlayingTrackTitle.
* Shuffling tracks does not affect the track index, just the track
* at that index. If an unshuffled track at playback index 1 is
* shuffled, a new track is placed into index 1. The playback
* indexes themselves are not shuffled.
* When shuffle mode is enabled, tracks that are marked 'skip when
* shuffling' are filtered from the database selection. This affects
* all audiobooks and all tracks that the user has marked in iTunes.
* It also affects all podcasts unless their default 'skip when
* shuffling' markings have been deliberately removed. To apply the
* filter to the playback engine, the accessory should send
* Command 0x0017: SelectDBRecord or
* Command 0x0028: PlayCurrentSelection after enabling shuffle mode.
*
* Note: Accessory developers are encouraged to always use the
* Restore on Exit byte with a nonzero value to restore any settings
* modified by the accessory upon detach.
*
* SetShuffle telegram with Restore on Exit byte
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x05 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2E Command ID (bits 7:0)
* 6 0xNN New shuffle mode. See above .
* 7 0xNN Restore on Exit byte. If 1, the orig setting is
* restored on detach; if 0, the newsetting persists
* after accessory detach.
* 8 0xNN Telegram payload checksum byte
*
* SetShuffle setting persistent after the accessory detach.
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2E Command ID (bits 7:0)
* 6 0xNN New shuffle mode. See above.
* 7 0xNN Telegram payload checksum byte
*
*/
if(buf[3] && !global_settings.playlist_shuffle)
{
global_settings.playlist_shuffle = 1;
settings_save();
if (audio_status() & AUDIO_STATUS_PLAY)
playlist_randomise(NULL, current_tick, true);
}
else if(!buf[3] && global_settings.playlist_shuffle)
{
global_settings.playlist_shuffle = 0;
settings_save();
if (audio_status() & AUDIO_STATUS_PLAY)
playlist_sort(NULL, true);
}
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x002F: /* GetRepeat */
{
/* The following is the description for the Apple Firmware
*
* Requests the track repeat state of the iPod. In response, the
* iPod sends a Command 0x0030: ReturnRepeat telegram
* to the device.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x2F Command ID (bits 7:0)
* 6 0xCA Telegram payload checksum byte
*
*/
unsigned char data[] = {0x04, 0x00, 0x30, 0x00};
if(global_settings.repeat_mode == REPEAT_OFF)
data[3] = 0;
else if(global_settings.repeat_mode == REPEAT_ONE)
data[3] = 1;
else
data[3] = 2;
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0030: /* ReturnRepeat. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the current iPod track repeat state to the device.
* The iPod sends this telegram in response to the Command
* 0x002F:GetRepeat command.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x30 Command ID (bits 7:0)
* 6 0xNN Repeat state. See Below.
* 7 0xNN Telegram payload checksum byte
*
* Repeat state values
* Value Meaning
* 0x00 Repeat off
* 0x01 Repeat one track
* 0x02 Repeat all tracks
* 0x03 - 0xFF Reserved
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0031: /* SetRepeat */
{
/* The following is the description for the Apple Firmware
*
* Sets the repeat state of the iPod. The iPod track repeat modes
* are listed above. In response, the iPod sends an ACK telegram
* with the command status.
*
* This telegram has an optional byte, byte 0x07, called the
* RestoreonExitbyte. This byte can be used to restore the original
* repeat setting in use when the accessory was attached to the
* iPod. A nonzero value restores the original repeat setting of
* the iPod when the accessory is detached. If this byte is zero,
* the repeat setting set by the accessory overwrites the original
* setting and persists after the accessory is detached from the
* iPod.
*
* Note: Accessory developers are encouraged to always use the
* Restore on Exit byte with a nonzero value to restore any
* settings modified by the accessory upon detach.
*
* SetRepeat telegram with Restore on Exit byte
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x05 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x31 Command ID (bits 7:0)
* 6 0xNN New repeat state. See above.
* 7 0xNN Restore on Exit byte. If 1, the original setting is
* restored on detach; if 0, the newsetting persists
* after accessory detach.
* 8 0xNN Telegram payload checksum byte
*
* SetRepeat setting persistent after the accessory detach.
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x31 Command ID (bits 7:0)
* 6 0xNN New repeat state. See above.
* 7 0xNN Telegram payload checksum byte
*
*/
int oldmode = global_settings.repeat_mode;
if (buf[3] == 0)
global_settings.repeat_mode = REPEAT_OFF;
else if (buf[3] == 1)
global_settings.repeat_mode = REPEAT_ONE;
else if (buf[3] == 2)
global_settings.repeat_mode = REPEAT_ALL;
if (oldmode != global_settings.repeat_mode)
{
settings_save();
if (audio_status() & AUDIO_STATUS_PLAY)
audio_flush_and_reload_tracks();
}
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0032: /* SetDisplayImage */
{
/* The following is the description for the Apple Firmware
* This sets a bitmap image
* that is displayed on the iPod display when connected to the
* device. It replaces the default checkmark bitmap image that is
* displayed when iPod is connected to an external device
*
* Sets a bitmap image that is shown on the iPod display when it is
* connected to the device. The intent is to allow third party
* branding when the iPod is communicating with an external device.
* An image downloaded using this mechanism replaces the default
* checkmark bitmap image that is displayed when iPod is connected
* to an external device. The new bitmap is retained in RAM for as
* long as the iPod remains powered. After a system reset or deep
* sleep state, the new bitmap is lost and the checkmark image
* restored as the default when the iPod next enters Extended
* Interface mode after power-up.
* Before setting a monochrome display image, the device can send
* the Command 0x0033: GetMonoDisplayImageLimits telegram to obtain
* the current iPod display width, height and pixel format.The
* monochrome display information returned in the Command 0x0034:
* ReturnMonoDisplayImageLimits telegram can be useful to the
* device in deciding which type of display image format is suitable
* for downloading to the iPod.
* On iPods withcolor displays, devices can send the Command 0x0039:
* GetColorDisplayImageLimits telegram to obtain the iPod color
* display width,height,and pixel formats. The color display
* information is returned in the Command 0x003A:
* ReturnColorDisplayImageLimits<74> telegram.
* To set a display image, the device must successfully send
* SetDisplayImage descriptor and data telegrams to the iPod. The
* SetDisplayImage descriptor telegram (telegram index 0x0000) must
* be sent first, as it gives the iPod a description of the image
* to be downloaded. This telegram is shown in below. The image
* descriptor telegram includes image pixel format, image width and
* height, and display row size (stride) in bytes. Optionally, the
* descriptor telegram may also contain the beginning data of the
* display image, as long as it remains within the maximum length
* limits of the telegram.
* Following the descriptor telegram, the SetDisplayImage data
* telegrams (telegram index 0x0001 - 0xNNNN) should be sent using
* sequential telegram indices until the entire image has been sent
* to the iPod.
*
* Note: The SetDisplayImage telegram payload length is limited to
* 500 bytes. This telegram length limit and the size and format of
* the display image generally determine the minimum number of
* telegrams that are required to set a display image.
*
* Note: Starting with the second generation iPod nano with version
* 1.1.2 firmware, the use of the SetDisplayImage command is
* limited to once every 15 seconds over USB transport. The iPod
* classic and iPod 3G nano apply this restriction to both USB and
* UART transports. Calls made to SetDisplayImage more frequently
* than every 15 seconds will return a successful ACK command, but
* the bitmap will not be displayed on the iPod<6F>s screen. Hence use
* of the SetDisplayImage command should be limited to drawing one
* bitmap image per accessory connect. The iPod touch will accept
* the SetDisplayImage command but will not draw it on the iPod<6F>s
* screen.
*
* Below shows the format of a descriptor telegram. This example
* assumes the display image descriptor data exceeds the small
* telegram payload capacity; a large telegram format is shown.
*
* SetDisplayImage descriptor telegram (telegram index = 0x0000)
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x00 Telegram payload marker (large format)
* 3 0xNN Large telegram payload length (bits 15:8)
* 4 0xNN Large telegram payload length (bits 7:0)
* 5 0x04 Lingo ID: Extended Interface lingo
* 6 0x00 Command ID (bits 15:8)
* 7 0x32 Command ID (bits 7:0)
* 8 0x00 Descriptor telegram index (bits 15:8). These fields
* uniquely identify each packet in the SetDisplayImage
* transaction. The first telegram is the Descriptor
* telegram and always starts with an index of 0x0000.
* 9 0x00 Descriptor telegram index (bits 7:0)
* 10 0xNN Display pixel format code. See Below.
* 11 0xNN Imagewidth in pixels (bits 15:8). The number of
* pixels, from left to right, per row.
* 12 0xNN Image width in pixels (bits 7:0)
* 13 0xNN Image height in pixels (bits 15:8). The number of
* rows, from top to bottom, in the image.
* 14 0xNN Image height in pixels (bits 7:0)
* 15 0xNN Row size (stride) in bytes (bits 31:24). The number of
* bytes representing one row of pixels. Each row is
* zero-padded to end on a 32-bit boundary. The
* cumulative size, in bytes, of the image data,
* transferred across all telegrams in this transaction
* is effectively (Row Size * Image Height).
* 16 0xNN Row size (stride) in bytes (bits 23:16)
* 17 0xNN Row size (stride) in bytes (bits 15:8)
* 18 0xNN Row size (stride) in bytes (bits 7:0)
* 19<31>N 0xNN Display image pixel data
* NN 0xNN Telegram payload checksum byte
*
* SetDisplayImage data telegram (telegram index = 0x0001 - 0xNNNN)
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x00 Telegram payload marker (large format)
* 3 0xNN Large telegram payload length (bits 15:8)
* 4 0xNN Large telegram payload length (bits 7:0)
* 5 0x04 Lingo ID: Extended Interface lingo
* 6 0x00 Command ID (bits 15:8)
* 7 0x32 Command ID (bits 7:0)
* 8 0xNN Descriptor telegram index (bits 15:8). These fields
* uniquely identify each packet in the SetDisplayImage
* transaction. The first telegram is the descriptor
* telegram, shown in Table 6-68 (page 97). The
* remaining n-1 telegrams are simply data telegrams,
* where n is determined by the size of the image.
* 9 0xNN Descriptor telegram index (bits 7:0)
* 10<31>N 0xNN Display image pixel data
* NN 0xNN Telegram payload checksum byte
*
* Note: A known issue causes SetDisplayImage data telegram
* lengths less than 11 bytes to return a bad parameter error (0x04)
* ACK on 3G iPods.
*
* The iPod display is oriented as a rectangular grid of pixels. In
* the horizontal direction (x-coordinate), the pixel columns are
* numbered, left to right, from 0 to Cmax. In the vertical
* direction (y-coordinate), the pixel rows are numbered, top to
* bottom, from 0 to Rmax. Therefore, an (x,y) coordinate of (0,0)
* represents the upper-leftmost pixel on the display and
* (Cmax,Rmax) represents the lower-rightmost pixel on the display.
* A portion of the iPod display pixel layout is shown below, where
* x is the column number, y is the row number, and (Cmax,Rmax)
* represents the maximum row and column numbers.
*
* Pixel layout
* x
* y 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 - Cmax,0
* 0,1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 - Cmax,1
* 0,2 1,2 2,2 3,2 4,2 5,2 6,2 7,2 - Cmax,2
* 0,3 1,3 2,3 3,3 4,3 5,3 6,3 7,3 - Cmax,3
* 0,4 1,4 2,4 3,4 4,4 5,4 6,4 7,4 - Cmax,4
* 0,5 1,5 2,5 3,5 4,5 5,5 6,5 7,5 - Cmax,5
* 0,6 1,6 2,6 3,6 4,6 5,6 6,6 7,6 - Cmax,6
* 0,7 1,7 2,7 3,7 4,7 5,7 6,7 7,7 - Cmax,7
* " " " " " " " " " "
* 0, 1, 2, 3, 4, 5, 6, 7, - Cmax,
* RmaxRmaxRmaxRmaxRmaxRmaxRmaxRmax Rmax
*
* Display pixel format codes
* Display pixel format Code Protocol version
* Reserved 0x00 N/A
* Monochrome, 2 bits per pixel 0x01 1.01
* RGB 565 color, little-endian, 16 bpp 0x02 1.09
* RGB 565 color, big-endian, 16 bpp 0x03 1.09
* Reserved 0x04-0xFF N/A
*
* iPods with color screens support all three image formats. All
* other iPods support only display pixel format 0x01 (monochrome,
* 2 bpp).
*
* Display Pixel Format 0x01
* Display pixel format 0x01 (monochrome, 2 bits per pixel) is the
* pixel format supported by all iPods. Each pixel consists of 2
* bits that control the pixel intensity. The pixel intensities and
* associated binary codes are listed below.
*
* 2 bpp monochrome pixel intensities
* Pixel Intensity Binary Code
* Pixel off (not visible) 00b
* Pixel on 25% (light grey) 01b
* Pixel on 50% (dark grey) 10b
* Pixel on 100% (black) 11b
*
* Each byte of image data contains four packed pixels. The pixel
* ordering within bytes and the byte ordering within 32 bits is
* shown below.
*
* Image Data Byte 0x0000
* Pixel0 Pixel1 Pixel2 Pixel3
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0x0001
* Pixel4 Pixel5 Pixel6 Pixel7
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0x0002
* Pixel8 Pixel9 Pixel10 Pixel11
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0x0003
* Pixel12 Pixel13 Pixel14 Pixel15
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0xNNNN
* PixelN PixelN+1 PixelN+2 PixelN+3
* 7 6 5 4 3 2 1 0
*
* Display Pixel Formats 0x02 and 0x03
* Display pixel format 0x02 (RGB 565, little-endian) and display
* pixel format 0x03 (RGB 565, big-endian) are available for use
* in all iPods with color screens. Each pixel consists of 16 bits
* that control the pixel intensity for the colors red, green, and
* blue.
* It takes two bytes to represent a single pixel. Red is
* represented by 5 bits, green is represented by 6 bits, and blue
* by the final 5 bits. A 32-bit sequence represents 2 pixels. The
* pixel ordering within bytes and the byte ordering within 32 bits
* for display format 0x02 (RGB 565, little-endian) is shown below.
*
* Image Data Byte 0x0000
* Pixel 0, lower 3 bits of green Pixel 0, all 5 bits of blue
* 7 6 5 4 3 2 1 0
* Image Data Byte 0x0001
* Pixel 0, all 5 bits of red Pixel 0,upper 3 bits of green
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0x0002
* Pixel 1, lower 3 bits of green Pixel 1, all 5 bits of blue
* 7 6 5 4 3 2 1 0
*
* Image Data Byte 0x0003
* Pixel 1, all 5 bits of red Pixel 1, upper 3 bits of green
* 7 6 5 4 3 2 1 0
*
* The format for display pixel format 0x03 (RGB 565, big-endian, 16
* bpp) is almost identical, with the exception that bytes 0 and 1
* are swapped and bytes 2 and 3 are swapped.
*
*/
cmd_ok(cmd);
break;
}
case 0x0033: /* GetMonoDisplayImageLimits */
{
/* The following is the description for the Apple Firmware
*
* Requests the limiting characteristics of the monochrome image
* that can be sent to the iPod for display while it is connected
* to the device. It can be used to determine the display pixel
* format and maximum width and height of a monochrome image to be
* set using the Command 0x0032: SetDisplayImage telegram. In
* response, the iPod sends a Command 0x0034:
* ReturnMonoDisplayImageLimits telegram to the device with the
* requested display information. The GetMonoDisplayImageLimits
* command is supported by iPods with either monochrome or color
* displays. To obtain color display image limits, use Command
* 0x0039: GetColorDisplayImageLimits.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x33 Command ID (bits 7:0)
* 6 0xC6 Telegram payload checksum byte
*
*/
unsigned char data[] = {0x04, 0x00, 0x34,
LCD_WIDTH >> 8, LCD_WIDTH & 0xff,
LCD_HEIGHT >> 8, LCD_HEIGHT & 0xff,
0x01};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0034: /* ReturnMonoDisplayImageLimits. See Above*/
/* The following is the description for the Apple Firmware
*
* Returns the limiting characteristics of the monochrome image that
* can be sent to the iPod for display while it is connected to the
* device. The iPod sends this telegram in response to the Command
* 0x0033: GetMonoDisplayImageLimits telegram. Monochrome display
* characteristics include maximum image width and height and the
* display pixel format.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x34 Command ID (bits 7:0)
* 6 0xNN Maximum image width in pixels (bits 15:8)
* 7 0xNN Maximum image width in pixels (bits 7:0)
* 8 0xNN Maximum image height in pixels (bits 15:8)
* 9 0xNN Maximumimage height in pixels (bits 7:0)
* 10 0xNN Display pixel format (see Table 6-70 (page 99)).
* 11 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0035: /* GetNumPlayingTracks */
{
/* The following is the description for the Apple Firmware
*
* Requests the number of tracks in the list of tracks queued to
* play on the iPod. In response, the iPod sends a Command 0x0036:
* ReturnNumPlayingTracks telegram with the count of tracks queued
* to play.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x35 Command ID (bits 7:0)
* 6 0xC4 Telegram payload checksum byte
*
*/
unsigned char data[] = {0x04, 0x00, 0x36,
0x00, 0x00, 0x00, 0x00};
unsigned long playlist_amt = playlist_amount();
put_u32(&data[3], playlist_amt);
iap_send_pkt(data, sizeof(data));
break;
}
case 0x0036: /* ReturnNumPlayingTracks. See Above */
/* The following is the description for the Apple Firmware
*
* Returns the number of tracks in the actual list of tracks queued
* to play, including the currently playing track (if any). The
* iPod sends this telegram in response to the Command 0x0035:
* GetNumPlayingTracks telegram.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x36 Command ID (bits 7:0)
* 6 0xNN Number of tracks playing(bits 31:24)
* 7 0xNN Number of tracks playing(bits 23:16)
* 8 0xNN Number of tracks playing (bits 15:8)
* 9 0xNN Number of tracks playing (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x0037: /* SetCurrentPlayingTrack */
/* The following is the description for the Apple Firmware
*
* Sets the index of the track to play in the Now Playing playlist
* on the iPod. The index that is specified here is obtained by
* sending the Command 0x0035: GetNumPlayingTracks and Command
* 0x001E: GetCurrentPlayingTrackIndex telegrams to obtain the
* number of playing tracks and the current playing track index,
* respectively. In response, the iPod sends an ACK telegram
* indicating the status of the command.
*
* Note: The behavior of this command has changed. Before the
* 2G nano, if this command was sent with the current playing track
* index the iPod would pause playback momentarily and then resume.
* Starting with the 2G nano, the iPod restarts playback of the
* current track from the beginning. Older iPods will not be
* updated to the new behavior.
*
* Note: This command is usable only when the iPod is in a playing
* or paused state. If the iPod is stopped, this command fails.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x07 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x37 Command ID (bits 7:0)
* 6 0xNN New current playing track index (bits 31:24)
* 7 0xNN New current playing track index (bits 23:16)
* 8 0xNN New current playing track index (bits 15:8)
* 9 0xNN New current playing track index (bits 7:0)
* 10 0xNN Telegram payload checksum byte
*
*/
{
int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
long tracknum = get_u32(&buf[3]);
audio_pause();
audio_skip(tracknum - playlist_next(0));
if (!paused)
audio_resume();
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0038: /* SelectSortDBRecord */
/* The following is the description for the Apple Firmware
*
* Selects one or more records in the iPod database, based on a
* category-relative index. For example, selecting category 2
* (Artist), record index 1, and sort order 3 (Album) results in a
* list of selected tracks (records) from the second artist in the
* artist list, sorted by album name. Selections are additive and
* limited by the category hierarchy. Subsequent selections are
* made based on the subset of records resulting from previous
* selections and not from the entire database. The database
* category types are shown above. The sort order options and codes
* are shown below.
*
* SelectSortDBRecord telegram
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x09 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x38 Command ID (bits 7:0)
* 6 0xNN Database category type.
* 7 0xNN Category record index (bits 31:24)
* 8 0xNN Category record index (bits 23:16)
* 9 0xNN Category record index (bits 15:8)
* 10 0xNN Category record index (bits 7:0)
* 11 0xNN Database sort type.
* 12 0xNN Telegram payload checksum byte
*
* Database sort order options
* Sort Order Code Protocol version
* Sort by genre 0x00 1.00
* Sort by artist 0x01 1.00
* Sort by composer 0x02 1.00
* Sort by album 0x03 1.00
* Sort by name 0x04 1.00
* Sort by playlist 0x05 1.00
* Sort by release date 0x06 1.08
* Reserved 0x07 - 0xFE N/A
* Use default sort type 0xFF 1.00
*
* The default order of song and audiobook tracks on the iPod is
* alphabetical by artist, then alphabetical by that artist's
* albums, then ordered according to the order of the tracks on the
* album.
* For podcasts, the default order of episode tracks is reverse
* chronological. That is, the newest ones are first,then
* alphabetical by podcast name.
* The SelectSortDBRecord command can be used to sort all the song
* and audiobook tracks on the iPod alphabetically as follows:
* 1. Command 0x0016: ResetDBSelection
* 2. Command 0x0018: GetNumberCategorizedDBRecords for the Playlist
* category.
* 3. SelectSortDBRecord based on the Playlist category, using a
* record index of 0 to select the All Tracks
* playlist and the sort by name (0x04) sort
* order.
* 4. GetNumberCategorizedDBRecords for the Track category.
* 5. Command 0x001A :RetrieveCategorizedDatabaseRecords based on
* the Track category, using a start index of 0
* and an end index of the number of records
* returned by the call to
* GetNumberCategorizedDBRecords in step 4.
*
* The sort order of artist names ignores certain articles such
* that the artist <20>The Doors<72> is sorted under the letter <20>D<EFBFBD> and
* not <20>T<EFBFBD>; this matches the behavior of iTunes. The sort order is
* different depending on the language setting used in the iPod.
* The list of ignored articles may change in the future without
* notice.
* The SelectDBRecord command may also be used to select a database
* record with the default sort order.
*
* Note: The sort order field is ignored for the Audiobook category.
* Audiobooks are automatically sorted by track title. The sort
* order for podcast tracks defaults to release date, with the
* newest track coming first.
*
* Selects one or more records in the iPod database, based on a
* category-relative index. This appears to be hardcoded hierarchy
* decided by Apple that the external devices follow.
* This is as follows for all except podcasts,
*
* All (highest level),
* Playlist,
* Genre or Media Kind,
* Artist or Composer,
* Album,
* Track or Audiobook (lowest)
*
* for Podcasts, the order is
*
* All (highest),
* Podcast,
* Episode
* Track (lowest)
*
* Categories are
*
* 0x00 Reserved
* 0x01 Playlist
* 0x02 Artist
* 0x03 Album
* 0x04 Genre
* 0x05 Track
* 0x06 Composer
* 0x07 Audiobook
* 0x08 Podcast
* 0x09 - 0xff Reserved
*
* Sort Order optiona and codes are
*
* 0x00 Sort by Genre
* 0x01 Sort by Artist
* 0x02 Sort by Composer
* 0x03 Sort by Album
* 0x04 Sort by Name (Song Title)
* 0x05 Sort by Playlist
* 0x06 Sort by Release Date
* 0x07 - 0xfe Reserved
* 0xff Use default Sort Type
*
* Packet format (offset in data[]: Description)
* 0x00: Lingo ID: Extended Interface Protocol Lingo, always 0x04
* 0x01-0x02: Command, always 0x0038
* 0x03: Database Category Type
* 0x04-0x07: Category Record Index
* 0x08 Database Sort Type
*
* On Rockbox, if the recordtype is playlist, we load the selected
* playlist and start playing from the first track.
* If the recordtype is track, we play that track from the current
* playlist.
* On anything else we just play the current track from the current
* playlist.
* cur_dbrecord[0] is the recordtype
* cur_dbrecord[1-4] is the u32 of the record number requested
* which might be a playlist or a track number depending on
* the value of cur_dbrecord[0]
*/
{
memcpy(cur_dbrecord, buf + 3, 5);
int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
unsigned int number_of_playlists = nbr_total_playlists();
uint32_t index;
uint32_t trackcount;
index = get_u32(&cur_dbrecord[1]);
trackcount = playlist_amount();
if ((cur_dbrecord[0] == 0x05) && (index > trackcount))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
if ((cur_dbrecord[0] == 0x01) && (index > (number_of_playlists + 1)))
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
switch (cur_dbrecord[0])
{
case 0x01: /* Playlist*/
{
if (index != 0x00) /* 0x00 is the On-The-Go Playlist and
we do nothing with it */
{
audio_pause();
audio_skip(-iap_get_trackindex());
playlist_sort(NULL, true);
last_selected_playlist = index;
seek_to_playlist(last_selected_playlist);
}
break;
}
case 0x02: /* Artist Do Nothing */
case 0x03: /* Album Do Nothing */
case 0x04: /* Genre Do Nothing */
case 0x06: /* Composer Do Nothing */
break;
case 0x05: /* Track*/
{
audio_pause();
audio_skip(-iap_get_trackindex());
playlist_sort(NULL, true);
audio_skip(index - playlist_next(0));
break;
}
}
if (!paused)
audio_resume();
/* respond with cmd ok packet */
cmd_ok(cmd);
break;
}
case 0x0039: /* GetColorDisplayImageLimits */
/* The following is the description for the Apple Firmware
*
* Requests the limiting characteristics of the color image that
* can be sent to the iPod for display while it is connected to
* the device. It can be used to determine the display pixel format
* and maximum width and height of a color image to be set using
* the Command 0x0032: SetDisplayImage telegram. In response, the
* iPod sends a Command 0x003A: ReturnColorDisplayImageLimits
* telegram to the device with the requested display information.
* This command is supported only by iPods with color displays.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x03 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x39 Command ID (bits 7:0)
* 6 0xC0 Telegram payload checksum byte
*
*/
{
/* Set the same as the ReturnMonoDisplayImageLimits */
unsigned char data[] = {0x04, 0x00, 0x3A,
LCD_WIDTH >> 8, LCD_WIDTH & 0xff,
LCD_HEIGHT >> 8, LCD_HEIGHT & 0xff,
0x01};
iap_send_pkt(data, sizeof(data));
break;
}
case 0x003A: /* ReturnColorDisplayImageLimits See Above */
/* The following is the description for the Apple Firmware
*
* Returns the limiting characteristics of the color image that can
* be sent to the iPod for display while it is connected to the
* device. The iPod sends this telegram in response to the Command
* 0x0039: GetColorDisplayImageLimits telegram. Display
* characteristics include maximum image width and height and the
* display pixel format.
*
* Note: If the iPod supports multiple display image formats, a five
* byte block of additional image width, height, and pixel format
* information is appended to the payload for each supported display
* format. The list of supported color display image formats
* returned by the iPod may change in future software versions.
* Devices must be able to parse a variable length list of supported
* color display formats to search for compatible formats.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0xNN Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x3A Command ID (bits 7:0)
* 6 0xNN Maximum image width in pixels (bits 15:8)
* 7 0xNN Maximum image width in pixels (bits 7:0)
* 8 0xNN Maximum image height in pixels (bits 15:8)
* 9 0xNN Maximum image height in pixels (bits 7:0)
* 10 0xNN Display pixel format (see Table 6-70 (page 99)).
* 11-N 0xNN Optional display image width, height, and pixel format
* for the second to nth supported display formats,
* if present.
* NN 0xNN Telegram payload checksum byte
*
*/
{
/* We should NEVER receive this command so ERROR if we do */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
case 0x003B: /* ResetDBSelectionHierarchy */
{
/* The following is the description for the Apple Firmware
*
* This command carries a single byte in its payload (byte 6). A
* hierarchy selection value of 0x01 means that the accessory wants
* to navigate the music hierarchy; a hierarchy selection value of
* 0x02 means that the accessory wants to navigate the video
* hierarchy.
*
* Byte Value Meaning
* 0 0xFF Sync byte (required only for UART serial)
* 1 0x55 Start of telegram
* 2 0x04 Telegram payload length
* 3 0x04 Lingo ID: Extended Interface lingo
* 4 0x00 Command ID (bits 15:8)
* 5 0x3B Command ID (bits 7:0)
* 6 0x01 or 0x02 Hierarchy selection
* 7 0xNN Telegram payload checksum byte
*
* Note: The iPod will return an error if a device attempts to
* enable an unsupported hierarchy, such as a video hierarchy on an
* iPod model that does not support video.
*/
dbrecordcount = 0;
cur_dbrecord[0] = 0;
put_u32(&cur_dbrecord[1],0);
switch (buf[3])
{
case 0x01: /* Music */
{
cmd_ok(cmd);
break;
}
default: /* Anything else */
{
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
}
}
default:
{
#ifdef LOGF_ENABLE
logf("iap: Unsupported Mode04 Command");
#endif
/* The default response is IAP_ACK_BAD_PARAM */
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
break;
}
}
}