3154 lines
149 KiB
C
3154 lines
149 KiB
C
|
/***************************************************************************
|
|||
|
* __________ __ ___.
|
|||
|
* 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"
|
|||
|
|
|||
|
/*
|
|||
|
* 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) {
|
|||
|
strlcpy(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);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
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:
|
|||
|
* <EFBFBD>0x00 = Success (OK)
|
|||
|
* 0x01 = ERROR: Unknown database category
|
|||
|
* <EFBFBD>0x02 = ERROR: Command failed
|
|||
|
* 0x03 = ERROR: Out of resources
|
|||
|
* 0x04 = ERROR: Bad parameter
|
|||
|
* 0x05 = ERROR: Unknown ID
|
|||
|
* 0x06 = Reserved
|
|||
|
* 0x07 = Accessory not authenticated
|
|||
|
* <EFBFBD>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 <EFBFBD>Command 0x000A: ReturnAudiobookSpeed<EFBFBD>
|
|||
|
* 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 = (is_wps_fading() || (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<EFBFBD>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();
|
|||
|
size_t len;
|
|||
|
|
|||
|
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:
|
|||
|
len = strlcpy((char *)&data[7], id3.title,64);
|
|||
|
break;
|
|||
|
case 0x02:
|
|||
|
len = strlcpy((char *)&data[7], id3.artist,64);
|
|||
|
break;
|
|||
|
case 0x03:
|
|||
|
len = strlcpy((char *)&data[7], id3.album,64);
|
|||
|
break;
|
|||
|
case 0x04:
|
|||
|
case 0x06:
|
|||
|
len = strlcpy((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 = (is_wps_fading() || (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 <EFBFBD> 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<EFBFBD> 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<EFBFBD>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<EFBFBD>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<EFBFBD>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<EFBFBD>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 = (is_wps_fading() || (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 <EFBFBD>The Doors<EFBFBD> is sorted under the letter <EFBFBD>D<EFBFBD> and
|
|||
|
* not <EFBFBD>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 = (is_wps_fading() || (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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|