usb: add usb iAP driver

add class driver source files.
also register iap audio sink.
usbstack/iap/libiap directory is imported from libiap.

Change-Id: I776c5caec33fe9efadc448e2e3b37d500bf19c9f
This commit is contained in:
mojyack 2025-12-19 20:45:16 +09:00 committed by Solomon Peachy
parent 2b9e4a8d70
commit 3bb656625b
193 changed files with 9650 additions and 1 deletions

View file

@ -957,6 +957,20 @@ usbstack/usb_charging_only.c
#ifdef USB_ENABLE_HID
usbstack/usb_hid.c
#endif
#ifdef USB_ENABLE_IAP
usbstack/iap/audio.c
usbstack/iap/buffer.c
usbstack/iap/debug.c
usbstack/iap/libiap/debug.c
usbstack/iap/libiap/fid-token-values.c
usbstack/iap/libiap/hid.c
usbstack/iap/libiap/iap.c
usbstack/iap/libiap/notification.c
usbstack/iap/libiap/span.c
usbstack/iap/notification.c
usbstack/iap/platform.c
usbstack/usb_iap.c
#endif
#if CONFIG_USBOTG == USBOTG_M66591
drivers/m66591.c
#elif CONFIG_USBOTG == USBOTG_ARC

View file

@ -1400,6 +1400,10 @@ Lyre prototype 1 */
#define USB_ENABLE_IAP
#endif
#if defined(USB_ENABLE_IAP)
#define HAVE_MULTIMEDIA_KEYS
#endif
#endif /* BOOTLOADER */
#endif /* HAVE_USBSTACK */

39
firmware/export/iap-usb.h Normal file
View file

@ -0,0 +1,39 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "config.h"
#ifdef USB_ENABLE_IAP
/* usbstack/iap/notification.c */
void iap_on_track_time_position(uint32_t pos_ms);
void iap_on_track_playback_index(uint32_t index, bool track_ready);
void iap_on_tracks_count(uint32_t count);
void iap_on_play_status(int status /* AUDIO_STATUS_* */);
void iap_on_volume(int volume);
void iap_on_shuffle_state(bool state);
void iap_on_repeat_state(int state);
#else
static inline void iap_on_track_time_position(uint32_t pos_ms) {
(void)pos_ms;
}
static inline void iap_on_track_playback_index(uint32_t index, bool track_ready) {
(void)index;
(void)track_ready;
}
static inline void iap_on_tracks_count(uint32_t count) {
(void)count;
}
static inline void iap_on_play_status(int status) {
(void)status;
}
static inline void iap_on_volume(int volume) {
(void)volume;
}
static inline void iap_on_shuffle_state(bool state) {
(void)state;
}
static inline void iap_on_repeat_state(int state) {
(void)state;
}
#endif

View file

@ -21,6 +21,8 @@
#include <stddef.h>
#include <stdint.h>
#include "config.h"
struct pcm_sink_caps {
const unsigned long* samprs;
uint16_t num_samprs;
@ -52,6 +54,9 @@ struct pcm_sink {
enum pcm_sink_ids {
PCM_SINK_BUILTIN = 0,
#ifdef USB_ENABLE_IAP
PCM_SINK_IAP,
#endif
PCM_SINK_NUM
};

View file

@ -172,6 +172,9 @@ enum {
#endif
#ifdef USB_ENABLE_AUDIO
USB_DRIVER_AUDIO,
#endif
#ifdef USB_ENABLE_IAP
USB_DRIVER_IAP,
#endif
USB_NUM_DRIVERS
};

View file

@ -77,8 +77,15 @@
*
*/
#ifdef USB_ENABLE_IAP
extern struct pcm_sink iap_pcm_sink;
#endif
static struct pcm_sink* sinks[PCM_SINK_NUM] = {
[PCM_SINK_BUILTIN] = &builtin_pcm_sink,
#ifdef USB_ENABLE_IAP
[PCM_SINK_IAP] = &iap_pcm_sink,
#endif
};
static enum pcm_sink_ids cur_sink = PCM_SINK_BUILTIN;

View file

@ -214,6 +214,9 @@ static inline void usb_configure_drivers(int for_state)
#ifdef USB_ENABLE_AUDIO
usb_core_enable_driver(USB_DRIVER_AUDIO, (usb_audio == 1) || (usb_audio == 2)); // while "always" or "only in charge-only mode"
#endif /* USB_ENABLE_AUDIO */
#ifdef USB_ENABLE_IAP
usb_core_enable_driver(USB_DRIVER_IAP, false);
#endif
#ifdef USB_ENABLE_CHARGING_ONLY
usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
@ -233,6 +236,9 @@ static inline void usb_configure_drivers(int for_state)
#ifdef USB_ENABLE_AUDIO
usb_core_enable_driver(USB_DRIVER_AUDIO, (usb_audio == 1) || (usb_audio == 3)); // while "always" or "only in mass-storage mode"
#endif /* USB_ENABLE_AUDIO */
#ifdef USB_ENABLE_IAP
usb_core_enable_driver(USB_DRIVER_IAP, true);
#endif
#ifdef USB_ENABLE_CHARGING_ONLY
usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false);
#endif

View file

@ -0,0 +1,268 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "core_alloc.h"
#include "pcm-internal.h"
#include "pcm_sampr.h"
#include "pcm_sink.h"
#include "system.h"
#include "usb_drv.h"
#include "../usb_iap.h"
#include "buffer.h"
#include "libiap/iap.h"
#include "macros.h"
#include "platform.h"
static const unsigned long samprs[] = {
SAMPR_48,
SAMPR_44,
};
struct StagingBuffer {
struct IAPAllocResult buf;
uint16_t cursor;
};
static struct StagingBuffer staging_buffers[USB_BATCH_SLOTS + 1]; /* +1 for silent buffer */
static int staging_buffer_index;
#define zero_buffer (staging_buffers[USB_BATCH_SLOTS])
static const uint8_t* pulled_buf;
static size_t pulled_buf_size;
static size_t pulled_buf_cursor;
static int8_t set_freq; /* requested freq from rockbox */
static int8_t cur_freq; /* requested freq from accessory */
static uint8_t packet_count;
static bool enabled;
static bool exhausted;
static bool track_attrs_sent;
extern struct pcm_sink iap_pcm_sink;
static void sink_set_freq(uint16_t freq) {
LOG("freq=%d", freq);
track_attrs_sent = true;
set_freq = freq;
struct IAPContext* ctx = _iap_acquire_ctx(true);
check_act(iap_select_sampr(ctx, samprs[freq]), );
_iap_release_ctx();
}
static size_t calc_packet_size(uint8_t cur_sampr, uint8_t packet_count) {
/* packet size calculation
* (4 = sizeof(int16_t) * channels)
* (1000 = usb frames per second)
* 48000Hz:
* 48000 * 4 / 1000 = 192.0
* => 192 + ...
* 44100Hz:
* 44100 * 4 / 1000 = 176.4
* => (9 * 176 + 180) + (...
*/
if(cur_sampr == 0) {
/*48k*/
return 192;
} else {
/*44.1k*/
return packet_count % 10 == 0 ? 180 : 176;
}
}
static void batch_get_more(const void** ptr, size_t* len) {
const size_t packet_size = calc_packet_size(cur_freq, packet_count);
#if 0
const int cur_frame = usb_drv_get_frame_number();
LOG("ex=%d set=%d cur=%d", exhausted, set_freq, cur_freq);
#endif
start:
if(exhausted || cur_freq != set_freq) {
*ptr = zero_buffer.buf.ptr;
*len = packet_size;
packet_count += 1;
return;
}
if(pulled_buf_cursor == pulled_buf_size) {
/* run out of previously pulled data.
* let's start filling them, by requesting new data from upstream */
if(!pcm_play_dma_complete_callback(PCM_DMAST_OK, (const void**)&pulled_buf, &pulled_buf_size)) {
/* no more data, but we have to keep sending something as long as the audio stream interface is enabled */
exhausted = true;
goto start;
}
/* pushing_{buf,buf_size} are filled. reset cursor and continue filling */
pcm_play_dma_status_callback(PCM_DMAST_STARTED);
pulled_buf_cursor = 0;
}
/* fill this single packet */
struct StagingBuffer* stage = &staging_buffers[staging_buffer_index];
const size_t copy = MIN(packet_size - stage->cursor, pulled_buf_size - pulled_buf_cursor);
memcpy(stage->buf.ptr + stage->cursor, pulled_buf + pulled_buf_cursor, copy);
pulled_buf_cursor += copy;
stage->cursor += copy;
#define AUDIO_STAT 0
#if AUDIO_STAT == 1
static int last_hz;
static int sample;
#endif
if(stage->cursor == packet_size) {
*ptr = stage->buf.ptr;
*len = stage->cursor;
stage->cursor = 0;
staging_buffer_index = (staging_buffer_index + 1) % USB_BATCH_SLOTS;
packet_count += 1;
#if AUDIO_STAT == 1
sample += packet_size / 4;
if(current_tick >= last_hz + HZ) {
logf("pushed %d %d", packet_size, sample);
sample = 0;
last_hz = current_tick;
}
#endif
} else { /* pushing_buf_cursor == pushing_buf_size */
goto start;
}
}
static void sink_play(const void* addr, size_t size) {
LOG("play");
pulled_buf = addr;
pulled_buf_size = size;
pulled_buf_cursor = 0;
exhausted = false;
/* resolve pending play request before sending TrackNewAudioAttributes (by sink_set_freq).
* some accessories will get confused when receiving it while waiting for an ack */
struct IAPContext* ctx = _iap_acquire_ctx(true);
struct Platform* plt = ctx->platform;
if(plt->control_pending) {
check_act(iap_control_response(ctx, plt->pending_control, true), );
plt->control_pending = false;
}
_iap_release_ctx();
/* rockbox only calls set_freq when changes occur, but we must call
* set_freq(and iap_select_sampr) at least once per connection. */
if(!track_attrs_sent) {
sink_set_freq(iap_pcm_sink.configured_freq);
}
}
static void sink_stop(void) {
LOG("stop");
/* we don't call usb_drv_batch_stop() here,
* because we need to send something, even not playing. */
}
static void sink_nop(void) {
}
struct pcm_sink iap_pcm_sink = {
.caps = {
.samprs = samprs,
.num_samprs = ARRAYLEN(samprs),
.default_freq = 0,
},
.ops = {
.init = sink_nop,
.postinit = sink_nop,
.set_freq = sink_set_freq,
.lock = sink_nop,
.unlock = sink_nop,
.play = sink_play,
.stop = sink_stop,
},
};
bool iap_audio_init(void) {
check_act(usb_drv_batch_init(AS_EP_IN, batch_get_more) == 0, return false);
for(size_t i = 0; i < ARRAYLEN(staging_buffers); i += 1) {
check_act(iap_alloc_usb_send_buffer(AS_PACKET_SIZE, &staging_buffers[i].buf), goto error);
staging_buffers[i].cursor = 0;
}
staging_buffer_index = 0;
memset(zero_buffer.buf.ptr, 0, AS_PACKET_SIZE);
set_freq = -1;
cur_freq = -2; /* something <0 && !=set_freq */
enabled = false;
exhausted = true;
track_attrs_sent = false;
packet_count = 0;
return true;
error:
for(size_t i = 0; i < ARRAYLEN(staging_buffers); i += 1) {
if(staging_buffers[i].buf.ptr != NULL) {
core_free(staging_buffers[i].buf.handle);
staging_buffers[i].buf.ptr = NULL;
}
}
return false;
}
bool iap_audio_deinit(void) {
check_act(usb_drv_batch_deinit() == 0, );
for(size_t i = 0; i < ARRAYLEN(staging_buffers); i += 1) {
core_free(staging_buffers[i].buf.handle);
staging_buffers[i].buf.ptr = NULL;
}
return true;
}
bool iap_audio_enable(void) {
LOG("enabled=%d", enabled);
check_act(enabled || usb_drv_batch_start() == 0, return false);
enabled = true;
return true;
}
bool iap_audio_disable(void) {
LOG("enabled=%d", enabled);
check_act(!enabled || usb_drv_batch_stop() == 0, return false);
enabled = false;
return true;
}
bool iap_audio_set_sampr(uint32_t sampr) {
uint16_t freq = 0;
for(; freq < ARRAYLEN(samprs); freq += 1) {
if(samprs[freq] == sampr) {
break;
}
}
check_act(freq < ARRAYLEN(samprs), return false);
cur_freq = freq;
LOG("sampr=%lu, set_freq=%d cur_freq=%d", sampr, set_freq, cur_freq);
return true;
}

View file

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#pragma once
#include <stdbool.h>
#include <stdint.h>
bool iap_audio_init(void);
bool iap_audio_deinit(void);
bool iap_audio_enable(void);
bool iap_audio_disable(void);
bool iap_audio_set_sampr(uint32_t sampr);

View file

@ -0,0 +1,47 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "core_alloc.h"
#include "buffer.h"
#include "macros.h"
bool iap_alloc_buffer(size_t size, struct IAPAllocResult* result) {
int handle = core_alloc_ex(size, &buflib_ops_locked);
check_act(handle > 0, return false);
uint8_t* ptr = core_get_data(handle);
result->handle = handle;
result->ptr = ptr;
return true;
}
bool iap_alloc_usb_send_buffer(size_t size, struct IAPAllocResult* result) {
/* + 31 to handle worst-case misalignment */
check_act(iap_alloc_buffer(size + 31, result), return false);
/* align to 32 */
result->ptr = (void*)((uintptr_t)(result->ptr + 31) & 0xffffffe0);
/* uncached */
#if defined(UNCACHED_ADDR) && CONFIG_CPU != AS3525
result->ptr = UNCACHED_ADDR(result->ptr);
#endif
return true;
}

View file

@ -0,0 +1,30 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#pragma once
#include <stdbool.h>
#include <stddef.h>
struct IAPAllocResult {
void* ptr;
int handle;
};
bool iap_alloc_buffer(size_t size, struct IAPAllocResult* result);
bool iap_alloc_usb_send_buffer(size_t size, struct IAPAllocResult* result);

View file

@ -0,0 +1,89 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "logf.h"
#include "system.h"
#include "tick.h"
#include "font.h"
#include "lcd.h"
#define MAX_COLS 64
static int rows;
static int columns;
static unsigned count;
static void update_color(void) {
unsigned avail = rows - 1;
if((count % (avail * 2)) > avail) {
lcd_set_drawinfo(DRMODE_SOLID, LCD_BLACK, LCD_WHITE);
} else {
lcd_set_drawinfo(DRMODE_SOLID, LCD_WHITE, LCD_BLACK);
}
}
void iap_lcd_scatter(const char* fmt, ...) {
if(rows == 0) {
int w, h;
font_getstringsize((unsigned char*)"A", &w, &h, FONT_SYSFIXED);
columns = MIN(LCD_WIDTH / w, MAX_COLS);
rows = LCD_HEIGHT / h;
}
va_list ap;
char buf[256];
va_start(ap, fmt);
int len = vsnprintf(buf, sizeof(buf), (char*)fmt, ap);
va_end(ap);
logf("%s", buf);
lcd_set_backdrop(NULL);
lcd_setfont(FONT_SYSFIXED);
update_color();
lcd_putsf(0, 0, (unsigned char*)"count %u", count);
for(int i = 0; i < len;) {
char line[MAX_COLS];
int copy = MIN(len - i, columns - 1);
memcpy(line, buf + i, copy);
memset(line + copy, ' ', columns - 1 - copy);
line[columns - 1] = '\0';
update_color();
lcd_puts(0, 1 + count % (rows - 1), (unsigned char*)line);
count += 1;
i += copy;
}
lcd_update();
}
static unsigned long timestamp_epoch;
unsigned long iap_debug_timestamp(void) {
return current_tick - timestamp_epoch;
}
void iap_debug_reset_timestamp(void) {
timestamp_epoch = current_tick;
}

View file

@ -0,0 +1,42 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 by Sho Tanimoto
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#pragma once
/* debug switches */
#define DEBUG_ENABLE_INFO 0
#define DEBUG_ENABLE_ERROR 1
#define DEBUG_LCD_PRINT 0
#define DEBUG_DUMP_TX 0
#define DEBUG_DUMP_RX 0
#define DEBUG_HEXDUMP_NOLIMIT 0
#if DEBUG_ENABLE_INFO == 1 || DEBUG_ENABLE_ERROR == 1
#define LOGF_ENABLE
#include "logf.h"
#endif
void iap_lcd_scatter(const char* fmt, ...);
unsigned long iap_debug_timestamp(void);
void iap_debug_reset_timestamp(void);
#if DEBUG_LCD_PRINT == 1
#undef logf
#define logf(...) iap_lcd_scatter(__VA_ARGS__)
#endif

View file

@ -0,0 +1,17 @@
#!/bin/bash
set -e
url=https://github.com/mojyack/libiap.git
src=/tmp/libiap
dst=$PWD/libiap
if [[ ! -e $src ]]; then
git clone "$url" "$src"
else
git -C "$src" pull
fi
rsync --recursive --delete "$src/src/iap/" "$dst/" --exclude /README.rockbox
cp "$src/LICENSE" "$dst/LICENSE"
git -C "$src" rev-parse HEAD > "$dst/HEAD"

View file

@ -0,0 +1 @@
ad06cdfc66f5db55d16b741df265269309105af3

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 mojyack
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,5 @@
Files under this directory were imported from libiap(https://github.com/mojyack/libiap) except for:
- README.rockbox: this file, Rockbox specific notes
- HEAD: libiap commit hash
To sync with the upstream, use ../libiap-sync.sh script.

View file

@ -0,0 +1,5 @@
#pragma once
typedef unsigned char IAPBool;
#define iap_true 1
#define iap_false 0

View file

@ -0,0 +1,11 @@
#pragma once
#define HID_BUFFER_SIZE 1024
#define SEND_BUFFER_SIZE 767 /* 0x2ff - 1: input_report_size_table_hs[0x0C].size - sizeof(report_id) */
enum IAPPhase {
IAPPhase_Connected = 0, /* initial state, waiting for StartIDPS */
IAPPhase_IDPS, /* idps started */
IAPPhase_Auth, /* idps completed, authenticating accessory */
IAPPhase_Authed, /* authentication completed, processing requests */
};

View file

@ -0,0 +1,107 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "bool.h"
#include "notification.h"
#include "platform.h"
struct IAPContext;
struct IAPSpan;
typedef IAPBool (*IAPOnSendComplete)(struct IAPContext* ctx);
struct IAPOpts {
/* indicate usb transport is highspeed */
IAPBool usb_highspeed : 1;
/* needed to support some accessories which don't set correct hid report id */
IAPBool ignore_hid_report_id : 1;
/* limit packet size while sending artworks for stability */
IAPBool artwork_single_report : 1;
/* dump each packets */
IAPBool enable_packet_dump : 1;
};
struct IAPContextButtons {
IAPBool play_pause : 1;
IAPBool volume_up : 1;
IAPBool volume_down : 1;
IAPBool next_track : 1;
IAPBool prev_track : 1;
IAPBool next_album : 1;
IAPBool prev_album : 1;
IAPBool stop : 1;
IAPBool play : 1;
IAPBool pause : 1;
IAPBool mute_toggle : 1;
IAPBool next_chapter : 1;
IAPBool prev_chapter : 1;
IAPBool next_playlist : 1;
IAPBool prev_playlist : 1;
IAPBool shuffle_advance : 1;
IAPBool repeat_advance : 1;
};
struct IAPActiveEvent;
typedef IAPBool (*IAPActiveEventReadyCallback)(struct IAPContext* ctx, struct IAPActiveEvent* event);
struct IAPActiveEvent {
IAPActiveEventReadyCallback callback;
union {
uint32_t sampr;
struct {
struct IAPPlatformPendingControl control;
IAPBool result;
} control_response;
};
};
struct IAPContext {
/* set by user */
void* platform; /* opaque to platform functions */
struct IAPOpts opts; /* options */
/* iap_feed_hid_report */
uint8_t* hid_recv_buf;
size_t hid_recv_buf_cursor;
/* _iap_send_packet, _iap_send_hid_reports */
uint8_t* send_buf;
size_t send_buf_sending_cursor;
size_t send_buf_sending_range_begin;
size_t send_buf_sending_range_end;
/* _iap_send_next_report */
/* for library-oriented, manageable events */
IAPOnSendComplete on_send_complete;
/* for user-oriented, unexpectable events */
struct IAPActiveEvent active_events[2];
/* _iap_feed_packet */
int32_t handling_trans_id;
/* iap.c */
struct IAPContextButtons context_button_state;
struct IAPPlatformArtwork artwork;
size_t artwork_cursor;
uint16_t trans_id;
uint16_t artwork_chunk_index;
int32_t artwork_trans_id;
uint16_t artwork_data_command;
uint8_t artwork_data_lingo;
uint8_t trans_id_support; /* TransIDSupport */
/* notification.c */
/* DisplayRemote::SetRemoteEventNotification */
uint32_t enabled_notifications_3;
uint32_t notifications_3;
/* ExtendedInterface::SetPlayStatusChangeNotification */
uint32_t enabled_notifications_4;
uint32_t notifications_4;
/* notification data */
struct _IAPNotifyState notification_data;
uint8_t notification_tick;
/* _iap_send_hid_reports */
uint8_t* hid_send_staging_buf;
IAPBool send_busy : 1;
IAPBool flushing_notifications : 1;
IAPBool waiting_for_audio_attrs_ack : 1;
uint8_t phase; /* IAPPhase */
};

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct IAPDateTime {
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t seconds;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
#pragma once
#include <stdint.h>
__attribute__((unused)) static uint8_t swap_8(uint8_t num) {
return num;
}
__attribute__((unused)) static uint16_t swap_16(uint16_t num) {
return (num >> 8) | (num << 8);
}
__attribute__((unused)) static uint32_t swap_32(uint32_t num) {
return (num & 0xFF000000) >> 24 |
(num & 0x00FF0000) >> 8 |
(num & 0x0000FF00) << 8 |
(num & 0x000000FF) << 24;
}
__attribute__((unused)) static uint64_t swap_64(uint64_t num) {
return (num & 0xFF00000000000000) >> 56 |
(num & 0x00FF000000000000) >> 40 |
(num & 0x0000FF0000000000) << 24 |
(num & 0x000000FF00000000) << 8 |
(num & 0x000000000FF00000) << 8 |
(num & 0x00000000000FF000) << 24 |
(num & 0x000000000000FF00) << 40 |
(num & 0x00000000000000FF) << 56;
}

View file

@ -0,0 +1,141 @@
#include "endian.h"
#include "iap.h"
#include "macros.h"
#include "span.h"
#include "spec/iap.h"
#define pack_accepted(Ack) \
struct Ack* const ack = iap_span_alloc(response, sizeof(*ack)); \
check_ret(ack != NULL, -IAPAckStatus_EOutOfResource); \
ack->length = sizeof(struct Ack) - 1; \
ack->type = token_header->type; \
ack->subtype = token_header->subtype; \
ack->status = IAPFIDTokenValuesIdentifyAckStatus_Accepted;
int _iap_hanlde_set_fid_token_values(struct IAPSpan* request, struct IAPSpan* response) {
const struct IAPSetFIDTokenValuesPayload* request_payload = iap_span_read(request, sizeof(*request_payload));
check_ret(request_payload != NULL, -IAPAckStatus_EBadParameter);
check_ret(iap_span_write_8(response, request_payload->num_token_values), -IAPAckStatus_EOutOfResource);
for(int i = 0; i < request_payload->num_token_values; i += 1) {
check_ret(request->size > sizeof(struct IAPFIDTokenValuesToken), -IAPAckStatus_EBadParameter);
struct IAPFIDTokenValuesToken* token_header = (void*)request->ptr;
struct IAPSpan token_span = {
request->ptr,
token_header->length + 1 /* length does not include sizeof itself */,
};
check_ret(request->size >= token_span.size, -IAPAckStatus_EBadParameter);
iap_span_read(request, token_span.size);
switch(token_header->type << 8 | token_header->subtype) {
case IAPFIDTokenTypes_Identify: {
/* IAPFIDTokenValuesIdentifyToken contains vla, need to parse manually */
const struct IAPFIDTokenValuesIdentifyTokenHead* token_head = iap_span_read(&token_span, sizeof(*token_head));
check_ret(token_head != NULL, -IAPAckStatus_EBadParameter);
for(int i = 0; i < token_head->num_lingoes; i += 1) {
uint8_t lingo_id;
check_ret(iap_span_read_8(&token_span, &lingo_id), -IAPAckStatus_EBadParameter);
}
const struct IAPFIDTokenValuesIdentifyTokenTail* token_tail = iap_span_read(&token_span, sizeof(*token_tail));
check_ret(token_tail != NULL, -IAPAckStatus_EBadParameter);
const uint32_t opt = swap_32(token_tail->device_option);
const uint32_t id = swap_32(token_tail->device_id);
pack_accepted(IAPFIDTokenValuesIdentifyAck);
if(opt != IAPIdentifyDeviceLingoesOptions_ImmediateAuth) {
ack->status = IAPFIDTokenValuesIdentifyAckStatus_RequiredFailed;
}
(void)id;
} break;
case IAPFIDTokenTypes_AccCaps: {
const struct IAPFIDTokenValuesAccCapsToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
const uint64_t caps = swap_64(token->caps_bits);
(void)caps;
pack_accepted(IAPFIDTokenValuesAccCapsAck);
} break;
case IAPFIDTokenTypes_AccInfo: {
const struct IAPFIDTokenValuesAccInfoToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
switch(token->info_type) {
case IAPFIDTokenValuesAccInfoTypes_AccName:
break;
case IAPFIDTokenValuesAccInfoTypes_FirmwareVersion:
check_ret(token_span.size == 3, -IAPAckStatus_EBadParameter);
break;
case IAPFIDTokenValuesAccInfoTypes_HardwareVersion:
check_ret(token_span.size == 3, -IAPAckStatus_EBadParameter);
break;
case IAPFIDTokenValuesAccInfoTypes_Manufacture:
break;
case IAPFIDTokenValuesAccInfoTypes_ModelNumber:
break;
case IAPFIDTokenValuesAccInfoTypes_SerialNumber:
break;
case IAPFIDTokenValuesAccInfoTypes_MaxPayloadSize: {
uint16_t val;
check_ret(iap_span_read_16(&token_span, &val), -IAPAckStatus_EBadParameter);
} break;
case IAPFIDTokenValuesAccInfoTypes_AccStatus: {
uint32_t val;
check_ret(iap_span_read_32(&token_span, &val), -IAPAckStatus_EBadParameter);
} break;
case IAPFIDTokenValuesAccInfoTypes_RFCerts: {
uint32_t val;
check_ret(iap_span_read_32(&token_span, &val), -IAPAckStatus_EBadParameter);
} break;
}
pack_accepted(IAPFIDTokenValuesAccInfoAck);
ack->info_type = token->info_type;
} break;
case IAPFIDTokenTypes_IPodPreference: {
const struct IAPFIDTokenValuesIPodPreferenceToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesIPodPreferenceAck);
ack->class_id = token->class_id;
} break;
case IAPFIDTokenTypes_EAProtocol: {
const struct IAPFIDTokenValuesEAProtocolToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesEAProtocolAck);
ack->protocol_index = token->protocol_index;
} break;
case IAPFIDTokenTypes_BundleSeedIDPref: {
const struct IAPFIDTokenValuesBundleSeedIDPrefToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesBundleSeedIDPrefAck);
} break;
case IAPFIDTokenTypes_ScreenInfo: {
const struct IAPFIDTokenValuesScreenInfoToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesScreenInfoAck);
} break;
case IAPFIDTokenTypes_EAProtocolMetadata: {
const struct IAPFIDTokenValuesEAProtocolMetadataToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesEAProtocolMetadataAck);
} break;
case IAPFIDTokenTypes_AccDigitalAudioSampleRates: {
const struct IAPFIDTokenValuesAccDigitalAudioSampleRatesToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
while(token_span.size > 0) {
uint32_t rate;
check_ret(iap_span_read_32(&token_span, &rate), -IAPAckStatus_EBadParameter);
}
pack_accepted(IAPFIDTokenValuesAccDigitalAudioSampleRatesAck);
} break;
case IAPFIDTokenTypes_AccDigitalAudioVideoDelay: {
const struct IAPFIDTokenValuesAccDigitalAudioVideoDelayToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesAccDigitalAudioVideoDelayAck);
} break;
case IAPFIDTokenTypes_MicrophoneCaps: {
const struct IAPFIDTokenValuesMicrophoneCapsToken* token = iap_span_read(&token_span, sizeof(*token));
check_ret(token != NULL, -IAPAckStatus_EBadParameter);
pack_accepted(IAPFIDTokenValuesMicrophoneCapsAck);
} break;
default:
warn("unknown fid %04X", token_header->type << 8 | token_header->subtype);
return -IAPAckStatus_EBadParameter;
}
}
return 0;
}

View file

@ -0,0 +1,181 @@
#include <string.h>
#include "constants.h"
#include "iap.h"
#include "macros.h"
#include "platform.h"
#include "spec/hid.h"
struct ReportSize {
uint8_t id;
uint16_t size; /* including link control byte */
};
/* must match to in-driver hid report descriptor */
static struct ReportSize input_report_size_table_fs[] = {
{.id = 0x01, .size = 0x0C},
{.id = 0x02, .size = 0x0E},
{.id = 0x03, .size = 0x14},
{.id = 0x04, .size = 0x3F},
};
static struct ReportSize output_report_size_table_fs[] = {
{.id = 0x05, .size = 0x08},
{.id = 0x06, .size = 0x0A},
{.id = 0x07, .size = 0x0E},
{.id = 0x08, .size = 0x14},
{.id = 0x09, .size = 0x3F},
};
static struct ReportSize input_report_size_table_hs[] = {
{.id = 0x01, .size = 0x0005},
{.id = 0x02, .size = 0x0009},
{.id = 0x03, .size = 0x000D},
{.id = 0x04, .size = 0x0011},
{.id = 0x05, .size = 0x0019},
{.id = 0x06, .size = 0x0031},
{.id = 0x07, .size = 0x005F},
{.id = 0x08, .size = 0x00C1},
{.id = 0x09, .size = 0x0101},
{.id = 0x0A, .size = 0x0181},
{.id = 0x0B, .size = 0x0201},
{.id = 0x0C, .size = 0x02FF},
};
static struct ReportSize output_report_size_table_hs[] = {
{.id = 0x0D, .size = 0x05},
{.id = 0x0E, .size = 0x09},
{.id = 0x1F, .size = 0x0D},
{.id = 0x10, .size = 0x11},
{.id = 0x11, .size = 0x19},
{.id = 0x12, .size = 0x31},
{.id = 0x13, .size = 0x5F},
{.id = 0x14, .size = 0xC1},
{.id = 0x15, .size = 0xFF},
};
static int find_output_report_size(struct IAPContext* ctx, uint8_t id) {
const struct ReportSize* ptr = ctx->opts.usb_highspeed ? output_report_size_table_hs : output_report_size_table_fs;
const size_t len = ctx->opts.usb_highspeed ? array_size(output_report_size_table_hs) : array_size(output_report_size_table_fs);
for(size_t i = 0; i < len; i += 1) {
if(ptr[i].id == id) {
return ptr[i].size;
}
}
return -1;
}
IAPBool iap_feed_hid_report(struct IAPContext* ctx, const uint8_t* const data, const size_t size) {
check_ret(size > sizeof(struct IAPHIDReport), iap_false);
struct IAPHIDReport* report = (struct IAPHIDReport*)data;
int report_size;
if(ctx->opts.ignore_hid_report_id) {
report_size = size - 1;
} else {
report_size = find_output_report_size(ctx, report->report_id);
check_ret(report_size == (int)size - 1, iap_false, "%d != %d", report_size, (int)size - 1);
}
const uint8_t payload_size = report_size - 1;
check_act(ctx->hid_recv_buf_cursor + payload_size <= HID_BUFFER_SIZE, { ctx->hid_recv_buf_cursor = 0; return iap_false; }, "hid buffer overflow");
if(!(report->link_control & IAPHIDReportLinkControlBits_Continue)) {
/* not continue, first packet */
if(ctx->hid_recv_buf_cursor != 0) {
warn("not continue and cursor was set");
ctx->hid_recv_buf_cursor = 0;
}
} else {
check_ret(ctx->hid_recv_buf_cursor > 0, iap_false);
}
memcpy(ctx->hid_recv_buf + ctx->hid_recv_buf_cursor, report->data, payload_size);
ctx->hid_recv_buf_cursor += payload_size;
if(!(report->link_control & IAPHIDReportLinkControlBits_MoreToFollow)) {
/* no more to follow, last packet */
const IAPBool ret = _iap_feed_packet(ctx, ctx->hid_recv_buf, ctx->hid_recv_buf_cursor);
ctx->hid_recv_buf_cursor = 0;
check_ret(ret, iap_false);
}
return iap_true;
}
IAPBool iap_notify_send_complete(struct IAPContext* ctx) {
ctx->send_busy = iap_false;
check_ret(_iap_send_next_report(ctx), iap_false);
return iap_true;
}
IAPBool _iap_send_hid_reports(struct IAPContext* ctx, size_t begin, size_t end) {
if(ctx->send_buf_sending_cursor < ctx->send_buf_sending_range_end) {
warn("another transmission in progress, aborting it");
}
ctx->send_buf_sending_cursor = begin;
ctx->send_buf_sending_range_begin = begin;
ctx->send_buf_sending_range_end = end;
if(!ctx->send_busy) {
check_ret(_iap_send_next_report(ctx), iap_false);
}
return iap_true;
}
static const struct ReportSize* find_optimal_report_size(struct IAPContext* ctx, size_t size) {
const struct ReportSize* ptr = ctx->opts.usb_highspeed ? input_report_size_table_hs : input_report_size_table_fs;
const size_t len = ctx->opts.usb_highspeed ? array_size(input_report_size_table_hs) : array_size(input_report_size_table_fs);
for(size_t i = 0; i < len; i += 1) {
if(ptr[i].size >= size + 1 /* link control byte*/) {
return &ptr[i];
}
}
return &ptr[len - 1];
}
IAPBool _iap_send_next_report(struct IAPContext* ctx) {
if(ctx->send_buf_sending_cursor >= ctx->send_buf_sending_range_end) {
if(ctx->on_send_complete != NULL) {
IAPOnSendComplete cb = ctx->on_send_complete;
ctx->on_send_complete = NULL;
check_ret(cb(ctx), iap_false);
} else if(ctx->active_events[0].callback != NULL) {
struct IAPActiveEvent event = ctx->active_events[0];
/* shift queue */
size_t i = 0;
for(; i < array_size(ctx->active_events) - 1 && ctx->active_events[i + 1].callback != NULL; i += 1) {
ctx->active_events[i] = ctx->active_events[i + 1];
}
ctx->active_events[i].callback = NULL;
/* process event */
check_ret(event.callback(ctx, &event), iap_false);
} else if(ctx->flushing_notifications) {
check_ret(_iap_flush_notification(ctx), iap_false);
}
return iap_true;
}
check_ret(!ctx->send_busy, iap_false);
const size_t send_buf_left = ctx->send_buf_sending_range_end - ctx->send_buf_sending_cursor;
const struct ReportSize* const report_size = find_optimal_report_size(ctx, send_buf_left);
const size_t take_size = min((size_t)report_size->size - 1 /* link control */, send_buf_left);
struct IAPHIDReport* const report = (struct IAPHIDReport*)ctx->hid_send_staging_buf;
report->report_id = report_size->id;
const IAPBool is_first = ctx->send_buf_sending_cursor == ctx->send_buf_sending_range_begin;
const IAPBool is_last = ctx->send_buf_sending_cursor + take_size == ctx->send_buf_sending_range_end;
report->link_control =
(!is_first ? IAPHIDReportLinkControlBits_Continue : 0) |
(!is_last ? IAPHIDReportLinkControlBits_MoreToFollow : 0);
memcpy(report->data, ctx->send_buf + ctx->send_buf_sending_cursor, take_size);
memset(report->data + take_size, 0, report_size->size - 1 - take_size); /* clear rest */
ctx->send_buf_sending_cursor += take_size;
ctx->send_busy = iap_true;
const size_t send_size = 1 + report_size->size;
check_ret(iap_platform_send_hid_report(ctx, report, send_size) == (int)send_size, iap_false);
return iap_true;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
#pragma once
#include "context.h"
#include "span.h"
#ifdef __cplusplus
extern "C" {
#endif
/* iap.c */
IAPBool iap_init_ctx(struct IAPContext* ctx, struct IAPOpts opts, void* platform);
IAPBool iap_deinit_ctx(struct IAPContext* ctx);
IAPBool _iap_feed_packet(struct IAPContext* ctx, const uint8_t* data, size_t size);
struct IAPSpan _iap_get_buffer_for_send_payload(struct IAPContext* ctx);
int32_t _iap_next_trans_id(struct IAPContext* ctx);
IAPBool _iap_send_packet(struct IAPContext* ctx, uint8_t lingo, uint16_t command, int32_t trans_id, uint8_t* final_ptr);
/* must be called after iap_platform_on_acc_samprs_received */
IAPBool iap_select_sampr(struct IAPContext* ctx, uint32_t sampr);
IAPBool iap_control_response(struct IAPContext* ctx, struct IAPPlatformPendingControl pending, IAPBool result);
/* hid.c */
IAPBool iap_feed_hid_report(struct IAPContext* ctx, const uint8_t* data, size_t size);
IAPBool iap_notify_send_complete(struct IAPContext* ctx);
IAPBool _iap_send_hid_reports(struct IAPContext* ctx, size_t begin, size_t end); /* data is passed by ctx->send_buf */
IAPBool _iap_send_next_report(struct IAPContext* ctx);
/* fid-token-values.c */
int _iap_hanlde_set_fid_token_values(struct IAPSpan* request, struct IAPSpan* response);
/* notification.c */
void iap_notify_track_time_position(struct IAPContext* ctx, uint32_t pos_ms);
void iap_notify_track_playback_index(struct IAPContext* ctx, uint32_t index);
void iap_notify_track_caps(struct IAPContext* ctx, uint32_t caps);
void iap_notify_tracks_count(struct IAPContext* ctx, uint32_t count);
void iap_notify_play_status(struct IAPContext* ctx, uint8_t status /* IAPIPodStatePlayStatus */);
void iap_notify_volume(struct IAPContext* ctx, uint8_t volume, IAPBool muted);
void iap_notify_power_state(struct IAPContext* ctx, uint8_t state /* IAPIPodStatePowerState */, uint8_t battery_level);
void iap_notify_shuffle_state(struct IAPContext* ctx, uint8_t state /* IAPIPodStateShuffleSettingState */);
void iap_notify_repeat_state(struct IAPContext* ctx, uint8_t state /* IAPIPodStateRepeatSettingState */);
void iap_notify_time_setting(struct IAPContext* ctx, const struct IAPDateTime* time);
void iap_notify_hold_switch_state(struct IAPContext* ctx, uint8_t state);
IAPBool iap_periodic_tick(struct IAPContext* ctx); /* call every 100ms */
IAPBool _iap_flush_notification(struct IAPContext* ctx);
/* debug.c */
const char* _iap_lingo_str(uint8_t lingo);
const char* _iap_command_str(uint8_t lingo, uint16_t command);
IAPBool _iap_span_is_str(const struct IAPSpan* span);
const char* _iap_span_as_str(const struct IAPSpan* span);
void _iap_dump_packet(uint8_t lingo, uint16_t command, int32_t trans_id, struct IAPSpan span);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,27 @@
#pragma once
#include "../platform-macros.h"
#if !defined(IAP_LOGF)
#define IAP_LOGF_MUTED
#define IAP_LOGF(...)
#endif
#define print(fmt, ...) IAP_LOGF("%s:%d: " fmt, __func__, __LINE__ __VA_OPT__(, __VA_ARGS__));
#if !defined(IAP_ERRORF)
#define IAP_ERRORF_MUTED
#define IAP_ERRORF(...)
#endif
#define warn(fmt, ...) IAP_ERRORF("%s:%d: " fmt, __func__, __LINE__ __VA_OPT__(, __VA_ARGS__));
#define check_act(cond, act, ...) \
if(!(cond)) { \
warn("assertion failed" __VA_OPT__(": " __VA_ARGS__)); \
act; \
}
#define check_ret(cond, ret, ...) check_act(cond, return ret, __VA_ARGS__)
#define array_size(arr) (sizeof(arr) / sizeof(arr[0]))
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)

View file

@ -0,0 +1,200 @@
#include "context.h"
#include "endian.h"
#include "iap.h"
#include "macros.h"
#include "spec/iap.h"
void iap_notify_track_time_position(struct IAPContext* ctx, uint32_t pos_ms) {
ctx->notification_data.track_time_position_ms = pos_ms;
ctx->notifications_3 |= 1 << IAPIPodStateType_TrackTimePositionMSec;
ctx->notifications_3 |= 1 << IAPIPodStateType_TrackTimePositionSec;
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_TrackTimeOffsetMSec;
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_TrackTimeOffsetSec;
}
void iap_notify_track_playback_index(struct IAPContext* ctx, uint32_t index) {
ctx->notification_data.track_playback_index = index;
ctx->notifications_3 |= 1 << IAPIPodStateType_TrackPlaybackIndex;
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_TrackIndex;
}
void iap_notify_track_caps(struct IAPContext* ctx, uint32_t caps) {
ctx->notification_data.track_caps = caps;
ctx->notifications_3 |= 1 << IAPIPodStateType_TrackCaps;
}
void iap_notify_tracks_count(struct IAPContext* ctx, uint32_t count) {
ctx->notification_data.tracks_count = count;
ctx->notifications_3 |= 1 << IAPIPodStateType_PlaybackEngineContents;
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_PlaybackEngineContentsChanged;
}
void iap_notify_play_status(struct IAPContext* ctx, uint8_t status) {
ctx->notification_data.play_status = status;
ctx->notifications_3 |= 1 << IAPIPodStateType_PlayStatus;
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_PlaybackStatusExtended;
if(status == IAPIPodStatePlayStatus_PlaybackStopped) {
ctx->notifications_4 |= 1 << IAPStatusChangeNotificationType_PlaybackStopped;
}
/* should set Playback{FEW,REW}SeekStop, but no way to find which from EndFastForwardRewind */
}
void iap_notify_volume(struct IAPContext* ctx, uint8_t volume, IAPBool muted) {
ctx->notification_data.volume = volume;
ctx->notification_data.mute_state = muted;
ctx->notifications_3 |= 1 << IAPIPodStateType_Volume;
}
void iap_notify_power_state(struct IAPContext* ctx, uint8_t state, uint8_t battery_level) {
ctx->notification_data.power_state = state;
ctx->notification_data.battery_level = battery_level;
ctx->notifications_3 |= 1 << IAPIPodStateType_Power;
}
void iap_notify_shuffle_state(struct IAPContext* ctx, uint8_t state) {
ctx->notification_data.shuffle_state = state;
ctx->notifications_3 |= 1 << IAPIPodStateType_ShuffleSetting;
}
void iap_notify_repeat_state(struct IAPContext* ctx, uint8_t state) {
ctx->notification_data.repeat_state = state;
ctx->notifications_3 |= 1 << IAPIPodStateType_RepeatSetting;
}
void iap_notify_time_setting(struct IAPContext* ctx, const struct IAPDateTime* time) {
ctx->notification_data.time_setting = *time;
ctx->notifications_3 |= 1 << IAPIPodStateType_DateTimeSetting;
}
void iap_notify_hold_switch_state(struct IAPContext* ctx, uint8_t state) {
ctx->notification_data.hold_switch_state = state;
ctx->notifications_3 |= 1 << IAPIPodStateType_HoldSwitchState;
}
IAPBool iap_periodic_tick(struct IAPContext* ctx) {
if(ctx->waiting_for_audio_attrs_ack) {
return iap_true;
}
ctx->flushing_notifications = iap_true;
ctx->notification_tick += 1;
if(!ctx->send_busy) {
check_ret(_iap_flush_notification(ctx), iap_false);
}
return iap_true;
}
static uint8_t play_status_to_extended(uint8_t status) {
switch(status) {
case IAPIPodStatePlayStatus_PlaybackStopped:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Stopped;
case IAPIPodStatePlayStatus_Playing:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Playing;
case IAPIPodStatePlayStatus_PlaybackPaused:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Paused;
case IAPIPodStatePlayStatus_FastForward:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_FFWSeekStarted;
case IAPIPodStatePlayStatus_FastRewind:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_REWSeekStarted;
case IAPIPodStatePlayStatus_EndFastForwardRewind:
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_FFWREWSeekStopped;
}
/* unreachable */
return IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Stopped;
}
#define send_notify_3(PayloadType, StateType, set) \
if(ctx->enabled_notifications_3 & ctx->notifications_3 & (1 << StateType)) { \
struct PayloadType* payload = iap_span_alloc(&request, sizeof(*payload)); \
check_ret(payload != NULL, iap_false); \
payload->type = StateType; \
set; \
check_ret(_iap_send_packet(ctx, IAPLingoID_DisplayRemote, IAPDisplayRemoteCommandID_RemoteEventNotification, _iap_next_trans_id(ctx), request.ptr), iap_false); \
ctx->notifications_3 &= ~(1 << StateType); \
return iap_true; \
}
#define send_notify_4(PayloadType, StateType, set) \
if(ctx->enabled_notifications_4 & ctx->notifications_4 & (1 << StateType)) { \
print("notification " #StateType); \
struct PayloadType* payload = iap_span_alloc(&request, sizeof(*payload)); \
check_ret(payload != NULL, iap_false); \
payload->type = StateType; \
set; \
check_ret(_iap_send_packet(ctx, IAPLingoID_ExtendedInterface, IAPExtendedInterfaceCommandID_PlayStatusChangeNotification, _iap_next_trans_id(ctx), request.ptr), iap_false); \
ctx->notifications_4 &= ~(1 << StateType); \
return iap_true; \
}
IAPBool _iap_flush_notification(struct IAPContext* ctx) {
struct IAPSpan request = _iap_get_buffer_for_send_payload(ctx);
/* [1] P.257:
* Notifications for enabled events are sent every 500 ms,
* with the exception of volume change notifications, which are sent every 100 ms.
*/
if(ctx->notification_tick % 5 != 0) {
goto freq_events;
}
send_notify_3(IAPIPodStateTrackTimePositionMSecPayload,
IAPIPodStateType_TrackTimePositionMSec,
payload->position_ms = swap_32(ctx->notification_data.track_time_position_ms));
send_notify_3(IAPIPodStateTrackPlaybackIndexPayload,
IAPIPodStateType_TrackPlaybackIndex,
payload->index = swap_32(ctx->notification_data.track_playback_index));
send_notify_3(IAPIPodStateTrackCapsPayload,
IAPIPodStateType_TrackCaps,
payload->caps = swap_32(ctx->notification_data.track_caps));
send_notify_3(IAPIPodStateTrackTimePositionSecPayload,
IAPIPodStateType_TrackTimePositionSec,
payload->position_s = swap_16(ctx->notification_data.track_time_position_ms / 1000));
send_notify_3(IAPIPodStatePlaybackEngineContentsPayload,
IAPIPodStateType_PlaybackEngineContents,
payload->count = swap_32(ctx->notification_data.tracks_count));
send_notify_3(IAPIPodStatePlayStatusPayload,
IAPIPodStateType_PlayStatus,
payload->status = ctx->notification_data.play_status);
send_notify_3(IAPIPodStatePowerPayload,
IAPIPodStateType_Power,
payload->power_state = ctx->notification_data.power_state;
payload->battery_level = ctx->notification_data.battery_level);
send_notify_3(IAPIPodStateShuffleSettingPayload,
IAPIPodStateType_ShuffleSetting,
payload->shuffle_state = ctx->notification_data.shuffle_state);
send_notify_3(IAPIPodStateRepeatSettingPayload,
IAPIPodStateType_RepeatSetting,
payload->repeat_state = ctx->notification_data.repeat_state);
send_notify_3(IAPIPodStateDateTimeSettingPayload,
IAPIPodStateType_DateTimeSetting,
payload->year = swap_16(ctx->notification_data.time_setting.year);
payload->month = ctx->notification_data.time_setting.month;
payload->day = ctx->notification_data.time_setting.day;
payload->hour = ctx->notification_data.time_setting.hour;
payload->minute = ctx->notification_data.time_setting.minute);
send_notify_4(IAPPlayStatusChangeNotificationPlaybackStoppedPayload,
IAPStatusChangeNotificationType_PlaybackStopped, );
send_notify_4(IAPPlayStatusChangeNotificationTrackIndexPayload,
IAPStatusChangeNotificationType_TrackIndex,
payload->index = swap_32(ctx->notification_data.track_playback_index));
send_notify_4(IAPPlayStatusChangeNotificationTrackTimeOffsetMSecPayload,
IAPStatusChangeNotificationType_TrackTimeOffsetMSec,
payload->offset_ms = swap_32(ctx->notification_data.track_time_position_ms));
send_notify_4(IAPPlayStatusChangeNotificationPlaybackStatusExtendedPayload,
IAPStatusChangeNotificationType_PlaybackStatusExtended,
payload->state = play_status_to_extended(ctx->notification_data.play_status));
send_notify_4(IAPPlayStatusChangeNotificationTrackTimeOffsetSecPayload,
IAPStatusChangeNotificationType_TrackTimeOffsetSec,
payload->offset_s = swap_32(ctx->notification_data.track_time_position_ms / 1000));
send_notify_4(IAPPlayStatusChangeNotificationPlaybackEngineContentsChangedPayload,
IAPStatusChangeNotificationType_PlaybackEngineContentsChanged,
payload->count = swap_32(ctx->notification_data.tracks_count));
freq_events:
send_notify_3(IAPIPodStateVolumePayload,
IAPIPodStateType_Volume,
payload->mute_state = ctx->notification_data.mute_state;
payload->ui_volume = ctx->notification_data.volume);
ctx->flushing_notifications = iap_false;
return iap_true;
}

View file

@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
#include "datetime.h"
struct _IAPNotifyState {
uint32_t track_time_position_ms;
uint32_t track_playback_index;
uint32_t track_caps; /* IAPIPodStateTrackCapBits */
uint32_t tracks_count;
uint8_t play_status; /* IAPIPodStatePlayStatus */
uint8_t mute_state;
uint8_t volume;
uint8_t power_state; /* IAPIPodStatePowerState */
uint8_t battery_level;
uint8_t shuffle_state; /* IAPIPodStateShuffleSettingState */
uint8_t repeat_state; /* IAPIPodStateRepeatSettingState */
struct IAPDateTime time_setting;
uint8_t hold_switch_state;
};

View file

@ -0,0 +1,41 @@
#include <stdint.h>
#include <string.h>
#include "bool.h"
#include "macros.h"
__attribute__((unused)) static IAPBool pack_u8(uint8_t** data, size_t* size, uint8_t value) {
check_ret(*size >= 1, iap_false);
(*data)[0] = value;
*data += 1;
*size -= 1;
return iap_true;
}
__attribute__((unused)) static IAPBool pack_u16(uint8_t** data, size_t* size, uint16_t value) {
check_ret(*size >= 2, iap_false);
(*data)[0] = value >> 8;
(*data)[1] = value;
*data += 2;
*size -= 2;
return iap_true;
}
__attribute__((unused)) static IAPBool pack_u32(uint8_t** data, size_t* size, uint32_t value) {
check_ret(*size >= 2, iap_false);
(*data)[0] = value >> 24;
(*data)[1] = value >> 16;
(*data)[2] = value >> 8;
(*data)[3] = value;
*data += 4;
*size -= 4;
return iap_true;
}
__attribute__((unused)) static IAPBool pack_data(uint8_t** data, size_t* size, const void* payload, size_t payload_size) {
check_ret(*size >= payload_size, iap_false);
memcpy(*data, payload, payload_size);
*data += payload_size;
*size -= payload_size;
return iap_true;
}

View file

@ -0,0 +1,116 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "datetime.h"
#include "span.h"
#include "spec/iap.h"
#ifdef __cplusplus
extern "C" {
#endif
struct IAPContext;
/* iap_platform_malloc */
enum IAPPlatformMallocFlags {
IAPPlatformMallocFlags_Uncached = 1 << 0,
};
/* iap_platform_get_play_status */
struct IAPPlatformPlayStatus {
uint32_t track_total_ms;
uint32_t track_pos_ms;
uint32_t track_index;
uint32_t track_count;
uint32_t track_caps; /* IAPIPodStateTrackCapBits */
uint8_t state; /* IAPIPodStatePlayStatus */
};
/* iap_platform_control */
enum IAPPlatformControl {
IAPPlatformControl_TogglePlayPause,
IAPPlatformControl_Play,
IAPPlatformControl_Pause,
IAPPlatformControl_Stop,
IAPPlatformControl_Next,
IAPPlatformControl_Prev,
IAPPlatformControl_VolumeUp,
IAPPlatformControl_VolumeDown,
IAPPlatformControl_ToggleMute,
};
struct IAPPlatformPendingControl {
uint16_t req_command;
uint16_t ack_command;
int32_t trans_id;
uint8_t lingo;
};
/* iap_platform_get_volume */
struct IAPPlatformVolumeStatus {
uint8_t volume;
IAPBool muted;
};
/* iap_platform_get_power_status */
struct IAPPlatformPowerStatus {
uint8_t state; /* IAPIPodStatePowerState */
uint8_t battery_level;
};
/* iap_platform_get_indexed_track_info */
struct IAPPlatformTrackInfo {
uint32_t* total_ms;
uint32_t* caps; /* IAPIPodStateTrackCapBits */
struct IAPDateTime* release_date;
struct IAPSpan* artist;
struct IAPSpan* composer;
struct IAPSpan* album;
struct IAPSpan* title;
};
/* iap_platform_open_artwork */
struct IAPPlatformArtwork {
uint16_t width; /* user */
uint16_t height; /* user */
IAPBool color; /* user */
IAPBool valid; /* library */
uintptr_t opaque; /* user */
};
/* library routines */
void* iap_platform_malloc(struct IAPContext* iap_ctx, size_t size, int flags);
void iap_platform_free(struct IAPContext* iap_ctx, void* ptr);
int iap_platform_send_hid_report(struct IAPContext* iap_ctx, const void* ptr, size_t size);
/* system info */
IAPBool iap_platform_get_ipod_serial_num(struct IAPContext* iap_ctx, struct IAPSpan* serial);
/* audio controls */
IAPBool iap_platform_get_play_status(struct IAPContext* iap_ctx, struct IAPPlatformPlayStatus* status);
void iap_platform_control(struct IAPContext* iap_ctx, enum IAPPlatformControl control, struct IAPPlatformPendingControl pending);
IAPBool iap_platform_get_volume(struct IAPContext* iap_ctx, struct IAPPlatformVolumeStatus* status);
IAPBool iap_platform_get_power_status(struct IAPContext* iap_ctx, struct IAPPlatformPowerStatus* status);
IAPBool iap_platform_get_shuffle_setting(struct IAPContext* iap_ctx, uint8_t* status /* IAPIPodStateShuffleSettingState */);
IAPBool iap_platform_set_shuffle_setting(struct IAPContext* iap_ctx, uint8_t status /* IAPIPodStateShuffleSettingState */);
IAPBool iap_platform_get_repeat_setting(struct IAPContext* iap_ctx, uint8_t* status /* IAPIPodStateRepeatSettingState */);
IAPBool iap_platform_set_repeat_setting(struct IAPContext* iap_ctx, uint8_t status /* IAPIPodStateRepeatSettingState */);
IAPBool iap_platform_get_date_time(struct IAPContext* iap_ctx, struct IAPDateTime* time);
IAPBool iap_platform_get_backlight_level(struct IAPContext* iap_ctx, uint8_t* level);
IAPBool iap_platform_get_hold_switch_state(struct IAPContext* iap_ctx, IAPBool* state);
IAPBool iap_platform_get_indexed_track_info(struct IAPContext* iap_ctx, uint32_t index, struct IAPPlatformTrackInfo* info);
IAPBool iap_platform_set_playing_track(struct IAPContext* iap_ctx, uint32_t index);
IAPBool iap_platform_open_artwork(struct IAPContext* iap_ctx, uint32_t index, struct IAPPlatformArtwork* artwork);
IAPBool iap_platform_get_artwork_ptr(struct IAPContext* iap_ctx, struct IAPPlatformArtwork* artwork, struct IAPSpan* span);
IAPBool iap_platform_close_artwork(struct IAPContext* iap_ctx, struct IAPPlatformArtwork* artwork);
/* other callbacks */
IAPBool iap_platform_on_acc_samprs_received(struct IAPContext* iap_ctx, struct IAPSpan* samprs);
/* debugging */
void iap_platform_dump_hex(const void* ptr, size_t size);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,46 @@
#include <string.h>
#include "endian.h"
#include "macros.h"
#include "span.h"
#include "unaligned.h"
const void* iap_span_read(struct IAPSpan* span, size_t count) {
check_ret(span->size >= count, NULL);
span->ptr += count;
span->size -= count;
return span->ptr - count;
}
void* iap_span_alloc(struct IAPSpan* span, size_t count) __attribute__((alias("iap_span_read")));
IAPBool iap_span_append(struct IAPSpan* span, const void* ptr, size_t size) {
void* dest = iap_span_alloc(span, size);
check_ret(dest != NULL, iap_false);
memcpy(dest, ptr, size);
return iap_true;
}
#define iap_span_template(width) \
IAPBool iap_span_peek_##width(struct IAPSpan* span, uint##width##_t* value) { \
check_ret(span->size >= width / 8, iap_false); \
*value = swap_##width(*(uu##width*)span->ptr); \
return iap_true; \
} \
IAPBool iap_span_read_##width(struct IAPSpan* span, uint##width##_t* value) { \
const uu##width* ptr = iap_span_read(span, width / 8); \
check_ret(ptr != NULL, iap_false); \
*value = swap_##width(*ptr); \
return iap_true; \
} \
IAPBool iap_span_write_##width(struct IAPSpan* span, uint##width##_t value) { \
uint##width##_t* ptr = iap_span_alloc(span, width / 8); \
check_ret(ptr != NULL, iap_false); \
*ptr = swap_##width(value); \
return iap_true; \
}
iap_span_template(8);
iap_span_template(16);
iap_span_template(32);
iap_span_template(64);
#undef iap_span_template

View file

@ -0,0 +1,32 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "bool.h"
struct IAPSpan {
uint8_t* ptr;
size_t size;
};
const void* iap_span_read(struct IAPSpan* span, size_t count);
void* iap_span_alloc(struct IAPSpan* span, size_t count);
IAPBool iap_span_append(struct IAPSpan* span, const void* ptr, size_t size);
#define iap_span_template(width) \
IAPBool iap_span_peek_##width(struct IAPSpan* span, uint##width##_t* value); \
IAPBool iap_span_read_##width(struct IAPSpan* span, uint##width##_t* value); \
IAPBool iap_span_write_##width(struct IAPSpan* span, uint##width##_t value)
iap_span_template(8);
iap_span_template(16);
iap_span_template(32);
iap_span_template(64);
#undef iap_span_template
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
/* [2] P.56 Table 3-2 Link control byte usage */
enum IAPHIDReportLinkControlBits {
IAPHIDReportLinkControlBits_Continue = 1 << 0,
IAPHIDReportLinkControlBits_MoreToFollow = 1 << 1,
};
struct IAPHIDReport {
uint8_t report_id;
uint8_t link_control; /* IAPHIDReportLinkControlBits */
uint8_t data[];
} __attribute__((packed));

View file

@ -0,0 +1,54 @@
#pragma once
/* References:
* [1]: MFi Accessory Firmware Specification R46
* [2]: MFI Accessory Hardware Specification R9
* [3]: MFi Accessory Interface Specification For Apple Devices R2
*/
#define IAP_SYNC_BYTE 0xFF
#define IAP_SOF_BYTE 0x55
/* [1] P.109 Table 2-10 iAP command packet format
* | name | size | description |
* | sync | 0 or 1 | IAP_SYNC_BYTE, exists if UART transport is used |
* | sof | 1 | IAP_SOF_BYTE |
* | length | 1 or 3 | 0xNN or 0x00NNNN. sum of length of {lingo,command,trans}_id,payload |
* | lingo_id | 1 | IAP_LINGO_ID, lingo identifier |
* | command_id | 1 or 2 | 2 bytes long if lingo == 4 |
* | trans_id | 0 or 2 | exists for some commands |
* | payload | N | data |
* | checksum | 1 | crc checksum |
*/
/* [1] P.211 Table 4-1 Additional iAP lingoes */
enum IAPLingoID {
IAPLingoID_General = 0x00,
IAPLingoID_Microphone = 0x01,
IAPLingoID_SimpleRemote = 0x02,
IAPLingoID_DisplayRemote = 0x03,
IAPLingoID_ExtendedInterface = 0x04,
IAPLingoID_AccessoryPower = 0x05,
IAPLingoID_USBHostMode = 0x06,
IAPLingoID_RFTuner = 0x07,
IAPLingoID_AccessoryEqualizer = 0x08,
IAPLingoID_Sports = 0x09,
IAPLingoID_DigitalAudio = 0x0A,
IAPLingoID_Storage = 0x0C,
IAPLingoID_IPodOut = 0x0D,
IAPLingoID_Location = 0x0E,
};
#include "lingoes/accessory-equalizer.h"
#include "lingoes/accessory-power.h"
#include "lingoes/digital-audio.h"
#include "lingoes/display-remote.h"
#include "lingoes/extended-interface.h"
#include "lingoes/general.h"
#include "lingoes/ipod-out.h"
#include "lingoes/location.h"
#include "lingoes/microphone.h"
#include "lingoes/rf-tuner.h"
#include "lingoes/simple-remote.h"
#include "lingoes/sports.h"
#include "lingoes/storage.h"
#include "lingoes/usb-host-mode.h"

View file

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
/* [1] P.331 Table 4-200 Accessory Equalizer lingo command summary */
enum IAPAccessoryEqualizerCommandID {
IAPAccessoryEqualizerCommandID_AccessoryAck = 0x00, /* from acc, general/acc-ack.h */
IAPAccessoryEqualizerCommandID_GetCurrentEQIndex = 0x01, /* from dev, no payload */
IAPAccessoryEqualizerCommandID_RetCurrentEQIndex = 0x02, /* from acc, current-eq-index.h */
IAPAccessoryEqualizerCommandID_SetCurrentEQIndex = 0x03, /* from dev, current-eq-index.h */
IAPAccessoryEqualizerCommandID_GetEQSettingCount = 0x04, /* from dev, no payload */
IAPAccessoryEqualizerCommandID_RetEQSettingCount = 0x05, /* from acc, eq-setting-count.h */
IAPAccessoryEqualizerCommandID_GetEQIndexName = 0x06, /* from dev, */
IAPAccessoryEqualizerCommandID_RetEQIndexName = 0x07, /* from acc, */
};
#include "accessory-equalizer/current-eq-index.h"
#include "accessory-equalizer/eq-index-name.h"
#include "accessory-equalizer/eq-setting-count.h"

View file

@ -0,0 +1,10 @@
#pragma once
#include <stdint.h>
struct IAPRetCurrentEQIndexPayload {
uint8_t index;
} __attribute__((packed));
struct IAPSetCurrentEQIndexPayload {
uint8_t index;
} __attribute__((packed));

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct IAGetEQIndexNamePayload {
uint8_t index;
} __attribute__((packed));
struct IARetEQIndexNamePayload {
uint8_t index;
char name[];
} __attribute__((packed));

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPRetEQSettingCountPayload {
uint8_t count;
} __attribute__((packed));

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
/* [1] P.548 Table C-37 Accessory Power lingo command summary */
enum IAPAccessoryPowerCommandID {
IAPAccessoryPowerCommandID_BeginHighPower = 0x02,
IAPAccessoryPowerCommandID_EndHighPower = 0x03,
};

View file

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
/* [1] P.346 Table 4-232 Digital Audio lingo command summary */
enum IAPDigitalAudioCommandID {
IAPDigitalAudioCommandID_AccessoryAck = 0x00, /* from acc, general/acc-ack.h */
IAPDigitalAudioCommandID_IPodAck = 0x01, /* from dev, general/ipod-ack.h */
IAPDigitalAudioCommandID_GetAccessorySampleRateCaps = 0x02, /* from dev, no payload */
IAPDigitalAudioCommandID_RetAccessorySampleRateCaps = 0x03, /* from acc, accessory-sample-rate-caps.h */
IAPDigitalAudioCommandID_TrackNewAudioAttributes = 0x04, /* from acc, track-new-audio-attributes.h */
IAPDigitalAudioCommandID_SetVideoDelay = 0x05, /* from acc, set-video-delay.h */
};
#include "digital-audio/accessory-sample-rate-caps.h"
#include "digital-audio/set-video-delay.h"
#include "digital-audio/track-new-audio-attributes.h"

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
/*
struct IAPRetAccessorySampleRateCapsPayload {
uint32_t sample_rates[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPSetVideoDelayPayload {
uint32_t delay_ms;
} __attribute__((packed));

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
struct IAPTrackNewAudioAttributesPayload {
uint32_t sample_rate;
uint32_t sound_check;
uint32_t volume_adjustment;
} __attribute__((packed));

View file

@ -0,0 +1,56 @@
#pragma once
#include <stdint.h>
/* [1] P.249 Table 4-48 Display Remote lingo command summary */
enum IAPDisplayRemoteCommandID {
IAPDisplayRemoteCommandID_IPodAck = 0x00, /* from acc, general/ipod-ack.h */
IAPDisplayRemoteCommandID_GetCurrentEQProfileIndex = 0x01, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetCurrentEQProfileIndex = 0x02, /* from dev, current-eq-profile-index.h */
IAPDisplayRemoteCommandID_SetCurrentEQProfileIndex = 0x03, /* from acc, current-eq-profile-index.h */
IAPDisplayRemoteCommandID_GetNumEQProfiles = 0x04, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetNumEQProfiles = 0x05, /* from dev, num-eq-profiles.h */
IAPDisplayRemoteCommandID_GetIndexedEQProfileName = 0x06, /* from acc, indexed-eq-profile-name.h */
IAPDisplayRemoteCommandID_RetIndexedEQProfileName = 0x07, /* from dev, indexed-eq-profile-name.h */
IAPDisplayRemoteCommandID_SetRemoteEventNotification = 0x08, /* from acc, ipod-state.h */
IAPDisplayRemoteCommandID_RemoteEventNotification = 0x09, /* from dev, ipod-state.h */
IAPDisplayRemoteCommandID_GetRemoteEventStatus = 0x0A, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetRemoteEventStatus = 0x0B, /* from dev, remote-event-status.h */
IAPDisplayRemoteCommandID_GetIPodStateInfo = 0x0C, /* from acc, ipod-state.h */
IAPDisplayRemoteCommandID_RetIPodStateInfo = 0x0D, /* from dev, ipod-state.h */
IAPDisplayRemoteCommandID_SetIPodStateInfo = 0x0E, /* from acc, ipod-state.h */
IAPDisplayRemoteCommandID_GetPlayStatus = 0x0F, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetPlayStatus = 0x10, /* from dev, play-status.h */
IAPDisplayRemoteCommandID_SetCurrentPlayingTrack = 0x11, /* from acc, set-current-playing-track.h */
IAPDisplayRemoteCommandID_GetIndexedPlayingTrackInfo = 0x12, /* from acc, indexed-playing-track-info.h */
IAPDisplayRemoteCommandID_RetIndexedPlayingTrackInfo = 0x13, /* from dev, indexed-playing-track-info.h */
IAPDisplayRemoteCommandID_GetNumPlayingTracks = 0x14, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetNumPlayingTracks = 0x15, /* from dev, num-playing-tracks.h */
IAPDisplayRemoteCommandID_GetArtworkFormats = 0x16, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetArtworkFormats = 0x17, /* from dev, artwork-formats.h */
IAPDisplayRemoteCommandID_GetTrackArtworkData = 0x18, /* from acc, track-artwork-data.h */
IAPDisplayRemoteCommandID_RetTrackArtworkData = 0x19, /* from dev, track-artwork-data.h */
IAPDisplayRemoteCommandID_GetPowerBatteryState = 0x1A, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetPowerBatteryState = 0x1B, /* from dev, power-battery-state.h */
IAPDisplayRemoteCommandID_GetSoundCheckState = 0x1C, /* from acc, no payload */
IAPDisplayRemoteCommandID_RetSoundCheckState = 0x1D, /* from dev, sound-check-status.h */
IAPDisplayRemoteCommandID_SetSoundCheckState = 0x1E, /* from acc, sound-check-status.h */
IAPDisplayRemoteCommandID_GetTrackArtworkTimes = 0x1F, /* from acc, track-artwork-times.h */
IAPDisplayRemoteCommandID_RetTrackArtworkTimes = 0x20, /* from dev, track-artwork-times.h */
IAPDisplayRemoteCommandID_CreateGeniusPlaylist = 0x21, /* from acc, genius_playlist.h */
IAPDisplayRemoteCommandID_IsGeniusAvailableForTrack = 0x22, /* from acc, genius_playlist.h */
};
#include "display-remote/artwork-formats.h"
#include "display-remote/current-eq-profile-index.h"
#include "display-remote/genius-playlist.h"
#include "display-remote/indexed-eq-profile-name.h"
#include "display-remote/indexed-playing-track-info.h"
#include "display-remote/ipod-state.h"
#include "display-remote/num-eq-profiles.h"
#include "display-remote/num-playing-tracks.h"
#include "display-remote/play-status.h"
#include "display-remote/power-battery-state.h"
#include "display-remote/remote-event-status.h"
#include "display-remote/set-current-playing-track.h"
#include "display-remote/track-artwork-data.h"
#include "display-remote/track-artwork-times.h"

View file

@ -0,0 +1,21 @@
#pragma once
#include <stdint.h>
enum IAPArtworkPixelFormats {
IAPArtworkPixelFormats_Mono = 0x01,
IAPArtworkPixelFormats_RGB565LE = 0x02,
IAPArtworkPixelFormats_RGB565BE = 0x03,
};
struct IAPArtworkFormat {
uint16_t format_id;
uint8_t pixel_format; /* IAPArtworkPixelFormats */
uint16_t image_width;
uint16_t image_height;
} __attribute__((packed));
/*
struct IAPRetArtworkFormatsPayload {
struct IAPArtworkFormat formats[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct IAPRetCurrentEQProfileIndexPayload {
uint32_t index;
} __attribute__((packed));
struct IAPSetCurrentEQProfileIndexPayload {
uint32_t index;
uint8_t restore_on_exit;
} __attribute__((packed));

View file

@ -0,0 +1,10 @@
#pragma once
#include <stdint.h>
struct IAPCreateGeniusPlaylistPayload {
uint32_t playback_index;
} __attribute__((packed));
struct IAPIsGeniusAvailableForTrackPayload {
uint32_t playback_index;
};

View file

@ -0,0 +1,12 @@
#pragma once
#include <stdint.h>
struct IAPGetIndexedEQProfileNamePayload {
uint32_t index;
} __attribute__((packed));
/*
struct IAPRetIndexedEQProfileNamePayload {
char name[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,85 @@
#pragma once
#include <stdint.h>
enum IAPIndexedPlayingTrackInfoType {
IAPIndexedPlayingTrackInfoType_TrackCapsInfo = 0x00,
IAPIndexedPlayingTrackInfoType_ChapterTimeName = 0x01,
IAPIndexedPlayingTrackInfoType_ArtistName = 0x02,
IAPIndexedPlayingTrackInfoType_AlbumName = 0x03,
IAPIndexedPlayingTrackInfoType_GenreName = 0x04,
IAPIndexedPlayingTrackInfoType_TrackTitle = 0x05,
IAPIndexedPlayingTrackInfoType_ComposerName = 0x06,
IAPIndexedPlayingTrackInfoType_Lyrics = 0x07,
IAPIndexedPlayingTrackInfoType_ArtworkCount = 0x08,
};
struct IAPGetIndexedPlayingTrackInfoPayload {
uint8_t type; /* IAPIndexedPlayingTrackInfoType */
uint32_t track_index;
uint16_t chapter_index;
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoPayload {
uint8_t type; /* IAPIndexedPlayingTrackInfoType */
uint8_t data[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoTrackCapsInfoPayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_TrackCapsInfo */
uint32_t track_caps; /* IAPIPodStateTrackCapBits */
uint32_t track_total_ms;
uint16_t chapter_count;
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoChapterTimeNamePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_ChapterTimeName */
uint32_t offset_ms;
char name[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoArtistNamePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_ArtistName */
char name[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoAlbumNamePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_AlbumName */
char name[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoGenreNamePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_GenreName */
char name[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoTrackTitlePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_TrackTitle */
char name[];
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoComposerNamePayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_ComposerName */
char name[];
} __attribute__((packed));
enum IAPIndexedPlayingTrackInfoLyricsInfoBits {
IAPIndexedPlayingTrackInfoLyricsInfoBits_Series = 1 << 0,
IAPIndexedPlayingTrackInfoLyricsInfoBits_Last = 1 << 1,
};
struct IAPRetIndexedPlayingTrackInfoLyricsPayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_Lyrics */
uint8_t info_bits; /* IAPIndexedPlayingTrackInfoLyricsInfoBits */
uint16_t index;
char lyrics[];
} __attribute__((packed));
struct IAPArtworkCount {
uint16_t format; /* IAPArtworkPixelFormats */
uint16_t count;
} __attribute__((packed));
struct IAPRetIndexedPlayingTrackInfoArtworkCountPayload {
uint8_t type; /* = IAPIndexedPlayingTrackInfoType_ArtworkCount */
struct IAPArtworkCount data[]; /* or 0x08 to indicate no counts */
} __attribute__((packed));

View file

@ -0,0 +1,204 @@
#pragma once
#include <stdint.h>
/* common state types */
/* [1] P.266 Table 4-74 Apple device state data */
enum IAPIPodStateType {
IAPIPodStateType_TrackTimePositionMSec = 0x00,
IAPIPodStateType_TrackPlaybackIndex = 0x01,
IAPIPodStateType_ChapterIndex = 0x02,
IAPIPodStateType_PlayStatus = 0x03,
IAPIPodStateType_Volume = 0x04,
IAPIPodStateType_Power = 0x05,
IAPIPodStateType_EQSetting = 0x06,
IAPIPodStateType_ShuffleSetting = 0x07,
IAPIPodStateType_RepeatSetting = 0x08,
IAPIPodStateType_DateTimeSetting = 0x09,
IAPIPodStateType_AlarmSetting = 0x0A,
IAPIPodStateType_BacklightLevel = 0x0B,
IAPIPodStateType_HoldSwitchState = 0x0C,
IAPIPodStateType_SoundCheckState = 0x0D,
IAPIPodStateType_AudiobookSpeeed = 0x0E,
IAPIPodStateType_TrackTimePositionSec = 0x0F,
IAPIPodStateType_AbsoluteVolume = 0x10,
IAPIPodStateType_TrackCaps = 0x11,
IAPIPodStateType_PlaybackEngineContents = 0x12,
};
struct IAPIPodStatePayload {
uint8_t type; /* IAPIPodStateType */
uint8_t data[];
} __attribute__((packed));
/* [1] P.257 Table 4-61 Event notification data */
struct IAPIPodStateTrackTimePositionMSecPayload {
uint8_t type; /* = IAPIPodStateType_TrackTimePositionMSec */
uint32_t position_ms;
} __attribute__((packed));
struct IAPIPodStateTrackPlaybackIndexPayload {
uint8_t type; /* = IAPIPodStateType_TrackPlaybackIndex */
uint32_t index;
} __attribute__((packed));
struct IAPIPodStateChapterIndexPayload {
uint8_t type; /* = IAPIPodStateType_ChapterIndex */
uint32_t index;
uint16_t chapter_count;
uint16_t chapter_index;
} __attribute__((packed));
enum IAPIPodStatePlayStatus {
IAPIPodStatePlayStatus_PlaybackStopped = 0x00,
IAPIPodStatePlayStatus_Playing = 0x01,
IAPIPodStatePlayStatus_PlaybackPaused = 0x02,
IAPIPodStatePlayStatus_FastForward = 0x03,
IAPIPodStatePlayStatus_FastRewind = 0x04,
IAPIPodStatePlayStatus_EndFastForwardRewind = 0x05,
};
struct IAPIPodStatePlayStatusPayload {
uint8_t type; /* = IAPIPodStateType_PlayStatus */
uint8_t status; /* IAPIPodStatePlayStatus */
} __attribute__((packed));
struct IAPIPodStateVolumePayload {
uint8_t type; /* = IAPIPodStateType_Volume */
uint8_t mute_state;
uint8_t ui_volume;
} __attribute__((packed));
enum IAPIPodStatePowerState {
IAPIPodStatePowerState_InternalLow = 0x00,
IAPIPodStatePowerState_Internal = 0x01,
IAPIPodStatePowerState_ExternalBattery = 0x02,
IAPIPodStatePowerState_External = 0x03,
IAPIPodStatePowerState_ExternalCharging = 0x04,
IAPIPodStatePowerState_ExternalCharged = 0x05,
};
struct IAPIPodStatePowerPayload {
uint8_t type; /* = IAPIPodStateType_Power */
uint8_t power_state; /* IAPIPodStatePowerState */
uint8_t battery_level;
} __attribute__((packed));
struct IAPIPodStateEQSettingPayload {
uint8_t type; /* = IAPIPodStateType_EQSetting */
uint32_t eq_index;
} __attribute__((packed));
enum IAPIPodStateShuffleSettingState {
IAPIPodStateShuffleSettingState_Off = 0x00,
IAPIPodStateShuffleSettingState_Tracks = 0x01,
IAPIPodStateShuffleSettingState_Albums = 0x02,
};
struct IAPIPodStateShuffleSettingPayload {
uint8_t type; /* = IAPIPodStateType_ShuffleSetting */
uint8_t shuffle_state; /* IAPIPodStateShuffleSettingState */
} __attribute__((packed));
enum IAPIPodStateRepeatSettingState {
IAPIPodStateRepeatSettingState_Off = 0x00,
IAPIPodStateRepeatSettingState_One = 0x01,
IAPIPodStateRepeatSettingState_All = 0x02,
};
struct IAPIPodStateRepeatSettingPayload {
uint8_t type; /* = IAPIPodStateType_RepeatSetting */
uint8_t repeat_state; /* IAPIPodStateRepeatSettingState */
} __attribute__((packed));
struct IAPIPodStateDateTimeSettingPayload {
uint8_t type; /* = IAPIPodStateType_DateTimeSetting */
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
} __attribute__((packed));
struct IAPIPodStateAlarmSettingPayload {
uint8_t type; /* = IAPIPodStateType_AlarmSetting */
uint8_t deprecated[3];
} __attribute__((packed));
struct IAPIPodStateBacklightLevelPayload {
uint8_t type; /* = IAPIPodStateType_BacklightLevel */
uint8_t level;
} __attribute__((packed));
struct IAPIPodStateHoldSwitchStatePayload {
uint8_t type; /* = IAPIPodStateType_HoldSwitchState */
uint8_t state;
} __attribute__((packed));
struct IAPIPodStateSoundCheckStatePayload {
uint8_t type; /* = IAPIPodStateType_SoundCheckState */
uint8_t state;
} __attribute__((packed));
enum IAPIPodStateAudiobookSpeeed {
IAPIPodStateAudiobookSpeeed_Slower = 0xFF,
IAPIPodStateAudiobookSpeeed_Normal = 0x00,
IAPIPodStateAudiobookSpeeed_Faster = 0x01,
};
struct IAPIPodStateAudiobookSpeeedPayload {
uint8_t type; /* = IAPIPodStateType_AudiobookSpeeed */
uint8_t speed; /* IAPIPodStateAudiobookSpeeed */
} __attribute__((packed));
struct IAPIPodStateTrackTimePositionSecPayload {
uint8_t type; /* = IAPIPodStateType_TrackTimePositionSec */
uint16_t position_s;
} __attribute__((packed));
struct IAPIPodStateAbsoluteVolumePayload {
uint8_t type; /* = IAPIPodStateType_AbsoluteVolume */
uint8_t mute_state;
uint8_t ui_volume;
uint8_t absolute_volume;
} __attribute__((packed));
enum IAPIPodStateTrackCapBits {
IAPIPodStateTrackCapBits_IsAudiobook = 1 << 0,
IAPIPodStateTrackCapBits_HasChapters = 1 << 1,
IAPIPodStateTrackCapBits_HasAlbumArts = 1 << 2,
IAPIPodStateTrackCapBits_HasLyrics = 1 << 3,
IAPIPodStateTrackCapBits_IsPodcast = 1 << 4,
IAPIPodStateTrackCapBits_HasReleaseDate = 1 << 5,
IAPIPodStateTrackCapBits_HasDescription = 1 << 6,
IAPIPodStateTrackCapBits_HasVideo = 1 << 7,
IAPIPodStateTrackCapBits_IsQueued = 1 << 8,
IAPIPodStateTrackCapBits_GenerateGeniusPlaylist = 1 << 13,
IAPIPodStateTrackCapBits_IsITunesUEpisode = 1 << 14,
};
struct IAPIPodStateTrackCapsPayload {
uint8_t type; /* = IAPIPodStateType_TrackCaps */
uint32_t caps; /* IAPIPodStateTrackCapBits */
} __attribute__((packed));
struct IAPIPodStatePlaybackEngineContentsPayload {
uint8_t type; /* = IAPIPodStateType_PlaybackEngineContents */
uint32_t count;
} __attribute__((packed));
/* event notification */
struct IAPSetRemoteEventNotificationPayload {
uint32_t mask; /* (1 << IAPIPodStateType) | ... */
} __attribute__((packed));
/* IAPRemoteEventNotificationPayload = IAPIPodStatePayload */
/* get/ret state info */
struct IAPGetIPodStateInfoPayload {
uint8_t type; /* = IAPIPodStateType */
} __attribute__((packed));
/* RetIPodStateInfoPayload = IAPIPodStatePayload */
/* SetIPodStateInfoPayload = IAPIPodStatePayload */

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPRetNumEQProfilesPayload {
uint32_t count;
} __attribute__((packed));

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPRetNumPlayingTracksPayload {
uint32_t num_playing_tracks;
} __attribute__((packed));

View file

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
struct IAPRetPlayStatusPayload {
uint8_t state; /* IAPIPodStatePlayStatus */
uint32_t track_index;
uint32_t track_total_ms;
uint32_t track_pos_ms;
} __attribute__((packed));

View file

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
struct IAPRetPowerBatteryStatePayload {
uint8_t power_state; /* IAPIPodStatePowerState */
uint8_t battery_level;
} __attribute__((packed));

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPRetRemoteEventStatusPayload {
uint32_t mask; /* (1 << IAPRemoteEventNotifications) | ... */
} __attribute__((packed));

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPSetCurrentPlayingTrackPayload {
uint32_t index;
} __attribute__((packed));

View file

@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
struct IAPGetTrackArtworkDataPayload {
uint32_t track_index;
uint16_t format_id;
uint32_t offset_ms;
} __attribute__((packed));
struct IAPRetTrackArtworkDataFirstPayload {
uint16_t index; /* = 0x0000 */
uint8_t pixel_format; /* IAPArtworkPixelFormats */
uint16_t pixel_width;
uint16_t pixel_height;
uint16_t inset_top_left_x;
uint16_t inset_top_left_y;
uint16_t inset_bottom_right_x;
uint16_t inset_bottom_right_y;
uint32_t stride;
uint8_t data[];
} __attribute__((packed));
struct IAPRetTrackArtworkDataSubsequenctPayload {
uint16_t index; /* > 0x0000 */
uint8_t data[];
} __attribute__((packed));

View file

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
struct IAPGetTrackArtworkTimesPayload {
uint32_t track_index;
uint16_t format_id;
uint16_t artwork_index;
uint16_t artwork_count;
} __attribute__((packed));
/*
struct IAPRetTrackArtworkTimesPayload {
uint32_t offsets_ms[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,109 @@
#pragma once
#include <stdint.h>
/* [1] P.398 Table 5-1 Extended Interface lingo command summary */
enum IAPExtendedInterfaceCommandID {
IAPExtendedInterfaceCommandID_IPodAck = 0x0001, /* 1.00, NoAuth, from acc, ipod-ack.h */
IAPExtendedInterfaceCommandID_GetCurrentPlayingTrackChapterInfo = 0x0002, /* 1.06, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnCurrentPlayingTrackChapterInfo = 0x0003, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_SetCurrentPlayingTrackChapter = 0x0004, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_GetCurrentPlayingTrackChapterPlayStatus = 0x0005, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_ReturnCurrentPlayingTrackChapterPlayStatus = 0x0006, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_GetCurrentPlayingTrackChapterName = 0x0007, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_ReturnCurrentPlayingTrackChapterName = 0x0008, /* 1.06, NoAuth, from dev, current-playing-track-chapter.h */
IAPExtendedInterfaceCommandID_GetAudiobookSpeed = 0x0009, /* 1.06, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_RetAudiobookSpeed = 0x000A, /* 1.06, NoAuth, from dev, audiobook-speed.h */
IAPExtendedInterfaceCommandID_SetAudiobookSpeed = 0x000B, /* 1.06, NoAuth, from acc, audiobook-speed.h */
IAPExtendedInterfaceCommandID_GetIndexedPlayingTrackInfo = 0x000C, /* 1.08, NoAuth, from acc, indexed-playing-track-info.h */
IAPExtendedInterfaceCommandID_ReturnIndexedPlayingTrackInfo = 0x000D, /* 1.08, NoAuth, from dev, indexed-playing-track-info.h */
IAPExtendedInterfaceCommandID_GetArtworkFormats = 0x000E, /* 1.10, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_RetArtworkFormats = 0x000F, /* 1.10, NoAuth, from dev, display-remote/artwork-formats.h*/
IAPExtendedInterfaceCommandID_GetTrackArtworkData = 0x0010, /* 1.10, NoAuth, from acc, display-remote/track-artwork-data.h*/
IAPExtendedInterfaceCommandID_RetTrackArtworkData = 0x0011, /* 1.10, NoAuth, from dev, display-remote/track-artwork-data.h*/
IAPExtendedInterfaceCommandID_RequestProtocolVersion = 0x0012, /* deprecated */
IAPExtendedInterfaceCommandID_ReturnProtocolVersion = 0x0013, /* deprecated */
IAPExtendedInterfaceCommandID_RequestIPodName = 0x0014, /* deprecated */
IAPExtendedInterfaceCommandID_ReturnIPodName = 0x0015, /* deprecated */
IAPExtendedInterfaceCommandID_ResetDBSelection = 0x0016, /* 1.00, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_SelectDBRecord = 0x0017, /* 1.00, NoAuth, from dev, database.h*/
IAPExtendedInterfaceCommandID_GetNumberCategorizedDBRecords = 0x0018, /* 1.00, NoAuth, from acc, database.h */
IAPExtendedInterfaceCommandID_ReturnNumberCategorizedDBRecords = 0x0019, /* 1.00, NoAuth, from dev, database.h */
IAPExtendedInterfaceCommandID_RetrieveCategorizedDatabaseRecords = 0x001A, /* 1.00, NoAuth, from acc, database.h */
IAPExtendedInterfaceCommandID_ReturnCategorizedDatabaseRecords = 0x001B, /* 1.00, NoAuth, from acc, database.h */
IAPExtendedInterfaceCommandID_GetPlayStatus = 0x001C, /* 1.00, NoAuth, no payload */
IAPExtendedInterfaceCommandID_ReturnPlayStatus = 0x001D, /* 1.00, NoAuth, play-status.h */
IAPExtendedInterfaceCommandID_GetCurrentPlayingTrackIndex = 0x001E, /* 1.00, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnCurrentPlayingTrackIndex = 0x001F, /* 1.00, NoAuth, from dev, current-playing-index.h */
IAPExtendedInterfaceCommandID_GetIndexedPlayingTrackTitle = 0x0020, /* 1.00, NoAuth, from acc, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_ReturnIndexedPlayingTrackTitle = 0x0021, /* 1.00, NoAuth, from dev, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_GetIndexedPlayingTrackArtistName = 0x0022, /* 1.00, NoAuth, from acc, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_ReturnIndexedPlayingTrackArtistName = 0x0023, /* 1.00, NoAuth, from dev, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_GetIndexedPlayingTrackAlbumName = 0x0024, /* 1.00, NoAuth, from acc, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_ReturnIndexedPlayingTrackAlbumName = 0x0025, /* 1.00, NoAuth, from dev, indexed-playing-track-string.h */
IAPExtendedInterfaceCommandID_SetPlayStatusChangeNotification = 0x0026, /* 1.00, NoAuth, from acc, play-status-change-notification.h */
IAPExtendedInterfaceCommandID_PlayStatusChangeNotification = 0x0027, /* 1.00, NoAuth, from dev, play-status-change-notification.h */
IAPExtendedInterfaceCommandID_PlayCurrentSelection = 0x0028, /* 1.00, NoAuth, from acc, play-current-selection.h */
IAPExtendedInterfaceCommandID_PlayControl = 0x0029, /* 1.00, NoAuth, from acc, play-control.h */
IAPExtendedInterfaceCommandID_GetTrackArtworkTimes = 0x002A, /* 1.10, NoAuth, from acc, display-remote/track-artwork-times.h */
IAPExtendedInterfaceCommandID_RetTrackArtworkTimes = 0x002B, /* 1.10, NoAuth, from dev, display-remote/track-artwork-times.h */
IAPExtendedInterfaceCommandID_GetShuffle = 0x002C, /* 1.00, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnShuffle = 0x002D, /* 1.00, NoAuth, from dev, shuffle.h */
IAPExtendedInterfaceCommandID_SetShuffle = 0x002E, /* 1.00, NoAuth, from acc, shuffle.h */
IAPExtendedInterfaceCommandID_GetRepeat = 0x002F, /* 1.00, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnRepeat = 0x0030, /* 1.00, NoAuth, from dev, repeat.h */
IAPExtendedInterfaceCommandID_SetRepeat = 0x0031, /* 1.00, NoAuth, from acc, repeat.h */
IAPExtendedInterfaceCommandID_SetDisplayImage = 0x0032, /* 1.01, NoAuth, from acc, set-display-image.h */
IAPExtendedInterfaceCommandID_GetMonoDisplayImageLimits = 0x0033, /* 1.01, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnMonoDisplayImageLimits = 0x0034, /* 1.01, NoAuth, from dev, mono-display-image-limits.h */
IAPExtendedInterfaceCommandID_GetNumPlayingTracks = 0x0035, /* 1.01, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnNumPlayingTracks = 0x0036, /* 1.01, NoAuth, from dev, display-remote/num-playing-tracks.h */
IAPExtendedInterfaceCommandID_SetCurrentPlayingTrack = 0x0037, /* 1.01, NoAuth, from acc, display-remote/set-current-playing-track.h */
IAPExtendedInterfaceCommandID_SelectSortDBRecord = 0x0038, /* deprecated */
IAPExtendedInterfaceCommandID_GetColorDisplayImageLimits = 0x0039, /* 1.09, NoAuth, from acc, no payload */
IAPExtendedInterfaceCommandID_ReturnColorDisplayImageLimits = 0x003A, /* 1.09, NoAuth, from dev, color-display-image-limits.h */
IAPExtendedInterfaceCommandID_ResetDBSelectionHierarchy = 0x003B, /* 1.11, Auth, from acc, db-selection-hierarchy.h */
IAPExtendedInterfaceCommandID_GetDBITunesInfo = 0x003C, /* 1.13, Auth, from acc, db-itunes-info.h */
IAPExtendedInterfaceCommandID_RetDBITunesInfo = 0x003D, /* 1.13, Auth, from dev, db-itunes-info.h */
IAPExtendedInterfaceCommandID_GetUIDTrackInfo = 0x003E, /* 1.13, Auth, from acc, track-info.h */
IAPExtendedInterfaceCommandID_RetUIDTrackInfo = 0x003F, /* 1.13, Auth, from dev, track-info.h */
IAPExtendedInterfaceCommandID_GetDBTrackInfo = 0x0040, /* 1.13, Auth, from acc, track-info.h */
IAPExtendedInterfaceCommandID_RetDBTrackInfo = 0x0041, /* 1.13, Auth, from dev, track-info.h */
IAPExtendedInterfaceCommandID_GetPBTrackInfo = 0x0042, /* 1.13, Auth, from acc, track-info.h */
IAPExtendedInterfaceCommandID_RetPBTrackInfo = 0x0043, /* 1.13, Auth, from dev, track-info.h */
IAPExtendedInterfaceCommandID_CreateGeniusPlaylist = 0x0044, /* 1.13, Auth, from acc, genius-playlist.h */
IAPExtendedInterfaceCommandID_RefreshGeniusPlaylist = 0x0045, /* 1.13, Auth, from acc, genius-playlist.h */
IAPExtendedInterfaceCommandID_IsGeniusAvailableForTrack = 0x0047, /* 1.13, Auth, from acc, genius-playlist.h */
IAPExtendedInterfaceCommandID_GetPlaylistInfo = 0x0048, /* 1.13, Auth, from acc, playlist-info.h */
IAPExtendedInterfaceCommandID_RetPlaylistInfo = 0x0049, /* 1.13, Auth, from dev, playlist-info.h */
IAPExtendedInterfaceCommandID_PrepareUIDList = 0x004A, /* 1.14, Auth, from dev, uid-list.h */
IAPExtendedInterfaceCommandID_PlayPreparedUIDList = 0x004B, /* 1.14, Auth, from dev, uid-list.h */
IAPExtendedInterfaceCommandID_GetArtworkTimes = 0x004C, /* 1.14, Auth, from acc, artwork-times.h */
IAPExtendedInterfaceCommandID_RetArtworkTimes = 0x004D, /* 1.14, Auth, from dev, artwork-times.h */
IAPExtendedInterfaceCommandID_GetArtworkData = 0x004E, /* 1.14, Auth, from acc, artwork-data.h */
IAPExtendedInterfaceCommandID_RetArtworkData = 0x004F, /* 1.14, Auth, from dev, artwork-data.h */
};
#include "extended-interface/artwork-data.h"
#include "extended-interface/artwork-times.h"
#include "extended-interface/audiobook-speed.h"
#include "extended-interface/color-display-image-limits.h"
#include "extended-interface/current-playing-track-chapter.h"
#include "extended-interface/current-playing-track-index.h"
#include "extended-interface/database.h"
#include "extended-interface/db-itunes-info.h"
#include "extended-interface/db-selection-hierarchy.h"
#include "extended-interface/genius-playlist.h"
#include "extended-interface/indexed-playing-track-info.h"
#include "extended-interface/indexed-playing-track-string.h"
#include "extended-interface/ipod-ack.h"
#include "extended-interface/mono-display-image-limits.h"
#include "extended-interface/play-control.h"
#include "extended-interface/play-current-selection.h"
#include "extended-interface/play-status-change-notification.h"
#include "extended-interface/play-status.h"
#include "extended-interface/playlist-info.h"
#include "extended-interface/repeat.h"
#include "extended-interface/set-display-image.h"
#include "extended-interface/shuffle.h"
#include "extended-interface/track-info.h"
#include "extended-interface/uid-list.h"

View file

@ -0,0 +1,58 @@
#pragma once
#include <stdint.h>
/* [1] P.459 5.1.72 Command 0x004E: GetArtworkData */
struct IAPGetArtworkDataPayload {
uint8_t id_type; /* IAPGetArtworkTrackIDType */
uint8_t data[];
} __attribute__((packed));
struct IAPGetArtworkDataUIDPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_UID */
uint8_t uid[8];
uint16_t format_id;
uint32_t offset_ms;
} __attribute__((packed));
struct IAPGetArtworkDataIndexPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_{PlaybackListIndex,DatabaseIndex} */
uint32_t index;
uint16_t format_id;
uint32_t offset_ms;
} __attribute__((packed));
struct IAPRetArtworkDataPayload {
uint16_t current_sector;
uint16_t max_sectors;
uint8_t id_type; /* = IAPGetArtworkTrackIDType */
uint8_t data[];
} __attribute__((packed));
struct IAPRetArtworkDataBody {
uint8_t pixel_format; /* IAPArtworkPixelFormats */
uint16_t pixel_width;
uint16_t pixel_height; /* [1] P.461 "Table 5-104 imageDescriptionAndData format" misses this field, but should be here */
uint16_t inset_top_left_x;
uint16_t inset_top_left_y;
uint16_t inset_bottom_right_x;
uint16_t inset_bottom_right_y;
uint32_t stride;
uint8_t data[];
} __attribute__((packed));
struct IAPRetArtworkDataUIDPayload {
uint16_t current_sector;
uint16_t max_sectors;
uint8_t id_type; /* = IAPGetArtworkTrackIDType_UID */
uint8_t uid[8];
struct IAPRetArtworkDataBody body;
} __attribute__((packed));
struct IAPRetArtworkDataIndexPayload {
uint16_t current_sector;
uint16_t max_sectors;
uint8_t id_type; /* = IAPGetArtworkTrackIDType_{PlaybackListIndex,DatabaseIndex} */
uint32_t index;
struct IAPRetArtworkDataBody body;
} __attribute__((packed));

View file

@ -0,0 +1,48 @@
#pragma once
#include <stdint.h>
/* [1] P.458 5.1.70 Command 0x004C: GetArtworkTimes */
enum IAPArtworkTrackIDType {
IAPGetArtworkTrackIDType_UID = 0x00,
IAPGetArtworkTrackIDType_PlaybackListIndex = 0x01,
IAPGetArtworkTrackIDType_DatabaseIndex = 0x02,
};
struct IAPGetArtworkTimesPayload {
uint8_t id_type; /* IAPGetArtworkTrackIDType */
uint8_t data[];
} __attribute__((packed));
struct IAPGetArtworkTimesUIDPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_UID */
uint8_t uid[8];
uint16_t format_id;
uint16_t artwork_index;
uint16_t artwork_count;
} __attribute__((packed));
struct IAPGetArtworkTimesIndexPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_{PlaybackListIndex,DatabaseIndex} */
uint32_t index;
uint16_t format_id;
uint16_t artwork_index;
uint16_t artwork_count;
} __attribute__((packed));
struct IAPRetArtworkTimesPayload {
uint8_t id_type; /* IAPGetArtworkTrackIDType */
uint8_t data[];
} __attribute__((packed));
struct IAPRetArtworkTimesUIDPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_UID */
uint8_t uid[8];
uint32_t offsets_ms[];
} __attribute__((packed));
struct IAPRetArtworkTimesIndexPayload {
uint8_t id_type; /* = IAPGetArtworkTrackIDType_{PlaybackListIndex,DatabaseIndex} */
uint32_t index;
uint32_t offsets_ms[];
} __attribute__((packed));

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct IAPRetAudiobookSpeedPayload {
uint8_t speed; /* IAPIPodStateAudiobookSpeeed */
} __attribute__((packed));
struct IAPSetAudiobookSpeedPayload {
uint8_t speed; /* IAPIPodStateAudiobookSpeeed */
uint8_t restore_on_exit; /* optional */
} __attribute__((packed));

View file

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
/* [1] P.443 5.1.53 Command 0x003A: ReturnColorDisplayImageLimits */
struct IAPColorDisplayImageLimit {
uint16_t max_width;
uint16_t max_height;
uint8_t pixel_format; /* IAPArtworkPixelFormats */
} __attribute__((packed));
/*
struct IAPReturnColorDisplayImageLimitsPayload {
struct IAPColorDisplayImageLimit limits[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,30 @@
#pragma once
#include <stdint.h>
struct IAPReturnCurrentPlayingTrackChapterInfoPayload {
uint32_t index;
uint32_t count;
} __attribute__((packed));
struct IAPSetCurrentPlayingTrackChapterPayload {
uint32_t index;
} __attribute__((packed));
struct IAPGetCurrentPlayingTrackChapterPlayStatusPayload {
uint32_t index;
} __attribute__((packed));
struct IAPReturnCurrentPlayingTrackChapterPlayStatusPayload {
uint32_t length_ms;
uint32_t elapsed_ms;
} __attribute__((packed));
struct IAPGetCurrentPlayingTrackChapterNamePayload {
uint32_t index;
} __attribute__((packed));
/*
struct IAPReturnCurrentPlayingTrackChapterNamePayload {
char name[];
} __attribute__((packed));
*/

View file

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
struct IAPReturnCurrentPlayingTrackIndexPayload {
uint32_t index;
} __attribute__((packed));

View file

@ -0,0 +1,42 @@
#pragma once
#include <stdint.h>
enum IAPDatabaseType {
IAPDatabaseType_TopLevel = 0x00, /* 1.14 */
IAPDatabaseType_Playlist = 0x01, /* 1.00 */
IAPDatabaseType_Artist = 0x02, /* 1.00 */
IAPDatabaseType_Album = 0x03, /* 1.00 */
IAPDatabaseType_Genre = 0x04, /* 1.00 */
IAPDatabaseType_Track = 0x05, /* 1.00 */
IAPDatabaseType_Composer = 0x06, /* 1.00 */
IAPDatabaseType_Audiobook = 0x07, /* 1.06 */
IAPDatabaseType_Podcast = 0x08, /* 1.08 */
IAPDatabaseType_NestedPlaylist = 0x09, /* 1.13 */
IAPDatabaseType_GeniusMixes = 0x0A, /* 1.14 */
IAPDatabaseType_ITunesU = 0x0B, /* 1.14 */
};
struct IAPSelectDBRecord {
uint8_t type; /* IAPDatabaseType */
uint32_t index;
} __attribute__((packed));
struct IAPGetNumberCategorizedDBRecordsPayload {
uint8_t type; /* IAPDatabaseType */
} __attribute__((packed));
struct IAPReturnNumberCategorizedDBRecordsPayload {
uint32_t count;
} __attribute__((packed));
struct IAPRetrieveCategorizedDatabaseRecordsPayload {
uint8_t type; /* IAPDatabaseType */
uint32_t index;
uint32_t count;
} __attribute__((packed));
struct IAPReturnCategorizedDatabaseRecordsPayload {
uint32_t index;
char record[];
} __attribute__((packed));

View file

@ -0,0 +1,42 @@
#pragma once
#include <stdint.h>
/* [1] P.444 5.1.55 Command 0x003C: GetDBiTunesInfo */
enum IAPITunesMetadataType {
IAPITunesMetadataType_UID = 0x00,
IAPITunesMetadataType_LastSyncDate = 0x01,
IAPITunesMetadataType_AudioTrackCount = 0x02,
IAPITunesMetadataType_VideoTrackCount = 0x03,
IAPITunesMetadataType_AudiobookCount = 0x04,
IAPITunesMetadataType_PhotoCount = 0x05,
};
struct IAPGetDBITunesInfoPayload {
uint8_t metadata_type; /* IAPITunesMetadataType */
} __attribute__((packed));
struct IAPRetDBITunesInfoPayload {
uint8_t metadata_type; /* = IAPITunesMetadataType */
uint8_t data[];
} __attribute__((packed));
struct IAPRetDBITunesInfoUIDPayload {
uint8_t metadata_type; /* = IAPITunesMetadataType_UID */
uint8_t uid[8];
} __attribute__((packed));
struct IAPRetDBITunesInfoLastSyncDatePayload {
uint8_t metadata_type; /* = IAPITunesMetadataType_LastSyncDate */
uint8_t seconds;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint16_t year;
} __attribute__((packed));
struct IAPRetDBITunesInfoCountPayload {
uint8_t metadata_type; /* = IAPITunesMetadataType_{AudioTrack,VideoTrack,Audiobook,Photo}Count */
uint32_t count;
} __attribute__((packed));

View file

@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
/* [1] P.443 5.1.54 Command 0x003B: ResetDBSelectionHierarchy */
enum IAPResetDBSelectionHierarchySelection {
IAPResetDBSelectionHierarchySelection_Audio = 0x01,
IAPResetDBSelectionHierarchySelection_Video = 0x02,
};
struct IAPResetDBSelectionHierarchyPayload {
uint8_t selection; /* IAPResetDBSelectionHierarchySelection */
} __attribute__((packed));

View file

@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
/* [1] P.454 5.1.63 Command 0x0044: CreateGeniusPlaylist */
enum IAPCreateGeniusPlaylistIndexType {
IAPCreateGeniusPlaylistIndexType_DatabaseEngine = 0x00,
IAPCreateGeniusPlaylistIndexType_PlaybackEngine = 0x01,
};
struct IAPExtendedCreateGeniusPlaylistPayload {
uint8_t index_type; /* IAPCreateGeniusPlaylistIndexType */
uint32_t index;
} __attribute__((packed));
struct IAPExtendedRefreshGeniusPlaylistPayload {
uint32_t index;
} __attribute__((packed));
struct IAPExtendedIsGeniusAvailableForTrackPayload {
uint8_t index_type; /* IAPCreateGeniusPlaylistIndexType */
uint32_t index;
} __attribute__((packed));

View file

@ -0,0 +1,81 @@
#pragma once
#include <stdint.h>
/* [1] P.408 5.1.13 Command 0x000C: GetIndexedPlayingTrackInfo */
enum IAPExtendedIndexedPlayingTrackInfoType {
IAPExtendedIndexedPlayingTrackInfoType_TrackCapsInfo = 0x00,
IAPExtendedIndexedPlayingTrackInfoType_PodcastName = 0x01,
IAPExtendedIndexedPlayingTrackInfoType_TrackReleaseDate = 0x02,
IAPExtendedIndexedPlayingTrackInfoType_TrackDescription = 0x03,
IAPExtendedIndexedPlayingTrackInfoType_TrackSongLyrics = 0x04,
IAPExtendedIndexedPlayingTrackInfoType_TrackGenre = 0x05,
IAPExtendedIndexedPlayingTrackInfoType_TrackComposer = 0x06,
IAPExtendedIndexedPlayingTrackInfoType_TrackArtworkCount = 0x07,
};
struct IAPExtendedGetIndexedPlayingTrackInfoPayload {
uint8_t type; /* IAPExtendedIndexedPlayingTrackInfoType */
uint32_t track_index;
uint16_t chapter_index;
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoPayload {
uint8_t type; /* IAPExtendedIndexedPlayingTrackInfoType */
uint8_t data[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackCapsInfoPayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackCapsInfo */
uint32_t track_caps; /* IAPIPodStateTrackCapBits */
uint32_t track_total_ms;
uint16_t chapter_count;
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoPodcastNamePayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_PodcastName */
char name[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackReleaseDatePayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackReleaseDate */
uint8_t seconds;
uint8_t minutes;
uint8_t hours;
uint8_t day;
uint8_t month;
uint16_t year;
uint8_t weekday;
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackDescriptionPayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackDescription */
uint8_t info_bits; /* IAPIndexedPlayingTrackInfoLyricsInfoBits */
uint16_t index;
char description[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackSongLyricsPayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackSongLyrics */
uint8_t info_bits; /* IAPIndexedPlayingTrackInfoLyricsInfoBits */
uint16_t index;
char lyrics[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackGenrePayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackGenre */
char genre[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackComposerPayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackComposer */
char composer[];
} __attribute__((packed));
struct IAPExtendedRetIndexedPlayingTrackInfoTrackArtworkCountPayload {
uint8_t type; /* = IAPExtendedRetIndexedPlayingTrackInfo_TrackArtworkCount */
struct {
uint16_t format; /* IAPArtworkPixelFormats */
uint16_t count;
} __attribute__((packed)) data[]; /* or 0x08 to indicate no counts */
} __attribute__((packed));

View file

@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
struct IAPGetIndexedPlayingTrackStringPayload {
uint32_t index;
} __attribute__((packed));
/* IAPGetIndexedPlayingTrackTitlePayload = IAPGetIndexedPlayingTrackStringPayload */
/* IAPGetIndexedPlayingTrackArtistNamePayload = IAPGetIndexedPlayingTrackStringPayload */
/* IAPGetIndexedPlayingTrackAlbumNamePayload = IAPGetIndexedPlayingTrackStringPayload */
/*
struct IAPReturnIndexedPlayingTrackStringPayload {
char string[];
} __attribute__((packed));
*/
/* IAPReturnIndexedPlayingTrackTitlePayload = IAPReturnIndexedPlayingTrackStringPayload */
/* IAPReturnIndexedPlayingTrackArtistNamePayload = IAPReturnIndexedPlayingTrackStringPayload */
/* IAPReturnIndexedPlayingTrackAlbumNamePayload = IAPReturnIndexedPlayingTrackStringPayload */

View file

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
struct IAPExtendedIPodAckPayload {
uint8_t status; /* IAPAckStatus */
uint16_t id;
} __attribute__((packed));

View file

@ -0,0 +1,10 @@
#pragma once
#include <stdint.h>
/* [1] P.440 5.1.48 Command 0x0034: ReturnMonoDisplayImageLimits */
struct IAPReturnMonoDisplayImageLimitsPayload {
uint16_t max_width;
uint16_t max_height;
uint8_t pixel_format; /* IAPArtworkPixelFormats */
} __attribute__((packed));

View file

@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
/* [1] P.428 5.1.37 Command 0x0029: PlayControl */
enum IAPPlayControlCode {
IAPPlayControlCode_TogglePlayPause = 0x01, /* 1.00 */
IAPPlayControlCode_Stop = 0x02, /* 1.00 */
IAPPlayControlCode_NextTrack = 0x03, /* 1.00 */
IAPPlayControlCode_PrevTrack = 0x04, /* 1.00 */
IAPPlayControlCode_StartFF = 0x05, /* 1.00 */
IAPPlayControlCode_StartRew = 0x06, /* 1.00 */
IAPPlayControlCode_EndFFRew = 0x07, /* 1.00 */
IAPPlayControlCode_Next = 0x08, /* 1.06 */
IAPPlayControlCode_Prev = 0x09, /* 1.06 */
IAPPlayControlCode_Play = 0x0A, /* 1.13 */
IAPPlayControlCode_Pause = 0x0B, /* 1.13 */
IAPPlayControlCode_NextChapter = 0x0C, /* 1.14 */
IAPPlayControlCode_PrevChapter = 0x0D, /* 1.14 */
IAPPlayControlCode_ResumeIPod = 0x0E, /* 1.14 */
};
struct IAPPlayControlPayload {
uint8_t code; /* IAPPlayControlCode */
};

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
/* [1] P.546 Table C-34 PlayCurrentSelection packet */
struct IAPPlayCurrentSelectionPayload {
uint32_t track_index;
} __attribute__((packed));

View file

@ -0,0 +1,137 @@
#pragma once
#include <stdint.h>
struct IAPSetPlayStatusChangeNotification1BytePayload {
uint8_t enable;
} __attribute__((packed));
enum IAPStatusChangeNotificationBits {
IAPStatusChangeNotificationBits_Basic = 1 << 0,
IAPStatusChangeNotificationBits_Extended = 1 << 1,
IAPStatusChangeNotificationBits_TrackIndex = 1 << 2,
IAPStatusChangeNotificationBits_TrackTimeOffsetMSec = 1 << 3,
IAPStatusChangeNotificationBits_TrackTimeOffsetSec = 1 << 4,
IAPStatusChangeNotificationBits_ChapterIndex = 1 << 5,
IAPStatusChangeNotificationBits_ChapterTimeOffsetMSec = 1 << 6,
IAPStatusChangeNotificationBits_ChapterTimeOffsetSec = 1 << 7,
IAPStatusChangeNotificationBits_TrackUniqueID = 1 << 8,
IAPStatusChangeNotificationBits_TrackMediaType = 1 << 9,
IAPStatusChangeNotificationBits_TrackLyricsReady = 1 << 10,
IAPStatusChangeNotificationBits_TrackCapsChanged = 1 << 11,
IAPStatusChangeNotificationBits_PlaybackEngineContentsChanged = 1 << 12,
};
struct IAPSetPlayStatusChangeNotification4BytesPayload {
uint32_t mask; /* IAPStatusChangeNotificationBits */
} __attribute__((packed));
/* [1] P.426 5.1.36 Command 0x0027: PlayStatusChangeNotification */
enum IAPStatusChangeNotificationType {
IAPStatusChangeNotificationType_PlaybackStopped = 0x00,
IAPStatusChangeNotificationType_TrackIndex = 0x01,
IAPStatusChangeNotificationType_PlaybackFEWSeekStop = 0x02,
IAPStatusChangeNotificationType_PlaybackREWSeekStop = 0x03,
IAPStatusChangeNotificationType_TrackTimeOffsetMSec = 0x04,
IAPStatusChangeNotificationType_ChapterIndex = 0x05,
IAPStatusChangeNotificationType_PlaybackStatusExtended = 0x06,
IAPStatusChangeNotificationType_TrackTimeOffsetSec = 0x07,
IAPStatusChangeNotificationType_ChapterTimeOffsetMSec = 0x08,
IAPStatusChangeNotificationType_ChapterTimeOffsetSec = 0x09,
IAPStatusChangeNotificationType_TrackUniqueID = 0x0A,
IAPStatusChangeNotificationType_TrackPlaybackMode = 0x0B,
IAPStatusChangeNotificationType_TrackLyricsReady = 0x0C,
IAPStatusChangeNotificationType_TrackCapsChanged = 0x0D,
IAPStatusChangeNotificationType_PlaybackEngineContentsChanged = 0x0E,
};
struct IAPPlayStatusChangeNotificationPayload {
uint8_t type;
uint8_t data[];
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationPlaybackStoppedPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_PlaybackStopped */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackIndexPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackIndex */
uint32_t index;
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationPlaybackFEWSeekStopPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_PlaybackFEWSeekStop */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationPlaybackREWSeekStopPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_PlaybackREWSeekStop */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackTimeOffsetMSecPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackTimeOffsetMSec */
uint32_t offset_ms;
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationChapterIndexPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_ChapterIndex */
uint32_t index;
} __attribute__((packed));
enum IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates {
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Stopped = 0x02,
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_FFWSeekStarted = 0x05,
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_REWSeekStarted = 0x06,
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_FFWREWSeekStopped = 0x07,
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Playing = 0x0A,
IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates_Paused = 0x0B,
};
struct IAPPlayStatusChangeNotificationPlaybackStatusExtendedPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_PlaybackStatusExtended */
uint8_t state; /* IAPPlayStatusChangeNotificationPlaybackStatusExtendedStates */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackTimeOffsetSecPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackTimeOffsetSec */
uint32_t offset_s;
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationChapterTimeOffsetMSecPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_ChapterTimeOffsetMSec */
uint32_t offset_ms;
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationChapterTimeOffsetSecPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_ChapterTimeOffsetSec */
uint32_t offset_s;
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackUniqueIDPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackUniqueID */
uint8_t id[8];
} __attribute__((packed));
enum IAPPlayStatusChangeNotificationTrackMediaTypePlayMode {
IAPPlayStatusChangeNotificationTrackMediaTypePlayMode_Audio = 0x00,
IAPPlayStatusChangeNotificationTrackMediaTypePlayMode_Video = 0x01,
};
struct IAPPlayStatusChangeNotificationTrackPlaybackModePayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackPlaybackMode */
uint8_t play_mode; /* IAPPlayStatusChangeNotificationTrackMediaTypePlayMode */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackLyricsReadyPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackLyricsReady */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationTrackCapsChangedPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_TrackCapsChanged */
uint32_t caps; /* IAPIPodStateTrackCapBits */
} __attribute__((packed));
struct IAPPlayStatusChangeNotificationPlaybackEngineContentsChangedPayload {
uint8_t type; /* = IAPStatusChangeNotificationType_PlaybackEngineContentsChanged */
uint32_t count;
} __attribute__((packed));

View file

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
enum IAPPlayStatus {
IAPPlayStatus_Stopped = 0x00,
IAPPlayStatus_Playing = 0x01,
IAPPlayStatus_Paused = 0x02,
IAPPlayStatus_Error = 0xFF,
};
struct IAPExtendedRetPlayStatusPayload {
uint32_t track_total_ms;
uint32_t track_pos_ms;
uint8_t state; /* IAPPlayStatus */
} __attribute__((packed));

View file

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
/* [1] P.456 5.1.66 Command 0x0048: GetPlaylistInfo */
enum IAPPlaylistInfoType {
PlaylistInfo = 0x00,
};
struct IAPGetPlaylistInfoPayload {
uint8_t info_type; /* IAPPlaylistInfoType */
uint32_t index;
} __attribute__((packed));
struct IAPRetPlaylistInfoPayload {
uint8_t info_type; /* IAPPlaylistInfoType */
uint8_t data; /* TODO: add definitions */
} __attribute__((packed));

View file

@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
/* [1] P.434 5.1.44 Command 0x0030: ReturnRepeat */
struct IAPReturnRepeatPayload {
uint8_t mode; /* IAPIPodStateRepeaetSettingState */
};
struct IAPSetRepeatPayload {
uint8_t mode; /* IAPIPodStateRepeatSettingState */
uint8_t restore_on_exit; /* optional */
};

View file

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
/* [1] P.435 5.1.46 Command 0x0032: SetDisplayImage */
struct IAPSetDisplayImageFirstPayload {
uint16_t index; /* = 0x0000 */
uint8_t pixel_format; /* IAPArtworkPixelFormats */
uint16_t pixel_width;
uint16_t pixel_height;
uint32_t stride;
uint8_t data[];
} __attribute__((packed));
struct IAPSetDisplayImageSubsequenctPayload {
uint16_t index; /* > 0x0000 */
uint8_t data[];
} __attribute__((packed));

View file

@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
/* [1] P.431 5.1.41 Command 0x002D: ReturnShuffle */
struct IAPReturnShufflePayload {
uint8_t mode; /* IAPIPodStateShuffleSettingState */
};
struct IAPSetShufflePayload {
uint8_t mode; /* IAPIPodStateShuffleSettingState */
uint8_t restore_on_exit; /* optional */
};

View file

@ -0,0 +1,59 @@
#pragma once
#include <stdint.h>
/* [1] P.446 5.1.57 Command 0x003E: GetUIDTrackInfo */
enum IAPTrakcInfoTypeBits {
/* mask[0] */
IAPTrakcInfoTypeBits_Caps = 1 << 0,
IAPTrakcInfoTypeBits_TrackName = 1 << 1,
IAPTrakcInfoTypeBits_ArtistName = 1 << 2,
IAPTrakcInfoTypeBits_AlbumName = 1 << 3,
IAPTrakcInfoTypeBits_GenreName = 1 << 4,
IAPTrakcInfoTypeBits_ComposerName = 1 << 5,
IAPTrakcInfoTypeBits_TotalTrackTimeDuration = 1 << 6,
IAPTrakcInfoTypeBits_UniqueTrackID = 1 << 7,
/* mask[1] */
IAPTrakcInfoTypeBits_ChapterCount = 1 << 0,
IAPTrakcInfoTypeBits_ChapterTimes = 1 << 1,
IAPTrakcInfoTypeBits_ChapterNames = 1 << 2,
IAPTrakcInfoTypeBits_Lyrics = 1 << 3,
IAPTrakcInfoTypeBits_Description = 1 << 4,
IAPTrakcInfoTypeBits_AlbumTrackIndex = 1 << 5,
IAPTrakcInfoTypeBits_DiscSetAlbumIndex = 1 << 6,
IAPTrakcInfoTypeBits_PlayCount = 1 << 7,
/* mask[2] */
IAPTrakcInfoTypeBits_SkipCount = 1 << 0,
IAPTrakcInfoTypeBits_PodcastReleaseDate = 1 << 1,
IAPTrakcInfoTypeBits_LastPlayedDate = 1 << 2,
IAPTrakcInfoTypeBits_Year = 1 << 3,
IAPTrakcInfoTypeBits_StarRating = 1 << 4,
IAPTrakcInfoTypeBits_SeriesName = 1 << 5,
IAPTrakcInfoTypeBits_SeasonNumber = 1 << 6,
IAPTrakcInfoTypeBits_TrackVolumeAdjust = 1 << 7,
/* mask[3] */
IAPTrakcInfoTypeBits_TrackEQPreset = 1 << 0,
IAPTrakcInfoTypeBits_TrackDataRate = 1 << 1,
IAPTrakcInfoTypeBits_BookmarkOffset = 1 << 2,
IAPTrakcInfoTypeBits_StartStopTimeOffset = 1 << 3,
};
struct IAPGetUIDTrackInfoPayload {
uint8_t uid[8];
uint32_t mask[]; /* IAPTrakcInfoTypeBits */
} __attribute__((packed));
struct IAPGetDBTrackInfoPayload {
uint8_t database_index;
uint8_t track_count;
uint32_t mask[]; /* IAPTrakcInfoTypeBits */
} __attribute__((packed));
struct IAPRetDBTrackInfoPayload {
uint8_t playing_index;
uint8_t track_count;
uint32_t mask[]; /* IAPTrakcInfoTypeBits */
} __attribute__((packed));
/* TODO: define IAPRet{UID,DB,PB}TrackInfoPayload, but who really needs this? */

View file

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
/* [1] P.457 5.1.68 Command 0x004A: PrepareUIDList */
struct IAPPrepareUIDListPayload {
uint16_t current_sector;
uint16_t max_sectors;
uint8_t uids[][8];
} __attribute__((packed));
struct IAPPlayPreparedUIDListPayload {
uint8_t reserved;
uint8_t uid[8];
};

View file

@ -0,0 +1,112 @@
#pragma once
#include <stdint.h>
/* [1] P.119 Table 3-1 General lingo commands */
enum IAPGeneralCommandID {
IAPGeneralCommandID_RequestIdentify = 0x00, /* 0.00, from dev, no payload */
IAPGeneralCommandID_Identify = 0x01, /* 0.00, from acc, identify.h, deprecated */
IAPGeneralCommandID_IPodAck = 0x02, /* 1.00, from dev, ipod-ack.h */
IAPGeneralCommandID_RequestExtendedInterfaceMode = 0x03, /* 1.00, from acc, no payload */
IAPGeneralCommandID_ReturnExtendedInterfaceMode = 0x04, /* 1.00, from dev, extended-interface-mode.h */
IAPGeneralCommandID_EnterExtendedInterfaceMode = 0x05, /* 1.00, from acc, no payload, deprecated */
IAPGeneralCommandID_ExitExtendedInterfaceMode = 0x06, /* 1.00, from acc, no payload */
IAPGeneralCommandID_RequestIPodName = 0x07, /* 1.00, from acc, no payload */
IAPGeneralCommandID_ReturnIPodName = 0x08, /* 1.00, from dev, ipod-name.h */
IAPGeneralCommandID_RequestIPodSoftwareVersion = 0x09, /* 1.00, from acc, no payload */
IAPGeneralCommandID_ReturnIPodSoftwareVersion = 0x0A, /* 1.00, from dev, ipod-software-version.h */
IAPGeneralCommandID_RequestIPodSerialNum = 0x0B, /* 1.00, from acc, no payload */
IAPGeneralCommandID_ReturnIPodSerialNum = 0x0C, /* 1.00, from dev, ipod-serial-num.h */
IAPGeneralCommandID_RequestIPodModelNum = 0x0D, /* 1.00, from acc, deprecated */
IAPGeneralCommandID_ReturnIPodModelNum = 0x0E, /* 1.00, from dev, deprecated */
IAPGeneralCommandID_RequestLingoProtocolVersion = 0x0F, /* 1.00, from acc, lingo-protocol-version.h */
IAPGeneralCommandID_ReturnLingoProtocolVersion = 0x10, /* 1.00, from dev, lingo-protocol-version.h */
IAPGeneralCommandID_RequestTransportMaxPayloadSize = 0x11, /* 1.09, from acc, no payload */
IAPGeneralCommandID_ReturnTransportMaxPayloadSize = 0x12, /* 1.09, from dev, transport-max-payload-size.h */
IAPGeneralCommandID_IdentifyDeviceLingoes = 0x13, /* 1.01, from acc, identify-device-lingoes.h */
IAPGeneralCommandID_GetAccessoryAuthenticationInfo = 0x14, /* 1.01, from dev, no payload */
IAPGeneralCommandID_RetAccessoryAuthenticationInfo = 0x15, /* 1.01, from acc, acc-auth-info.h */
IAPGeneralCommandID_AckAccessoryAuthenticationInfo = 0x16, /* 1.01, from dev, acc-auth-info.h */
IAPGeneralCommandID_GetAccessoryAuthenticationSignature = 0x17, /* 1.01, from dev, acc-auth-sig.h */
IAPGeneralCommandID_RetAccessoryAuthenticationSignature = 0x18, /* 1.01, from acc, acc-auth-sig.h */
IAPGeneralCommandID_AckAccessoryAuthenticationStatus = 0x19, /* 1.01, from dev, acc-auth-sig.h*/
IAPGeneralCommandID_GetIPodAuthenticationInfo = 0x1A, /* 1.01, from acc, no payload */
IAPGeneralCommandID_RetIPodAuthenticationInfo = 0x1B, /* 1.01, from dev, ipod-auth-info.h */
IAPGeneralCommandID_AckIPodAuthenticationInfo = 0x1C, /* 1.01, from acc, ipod-auth-info.h */
IAPGeneralCommandID_GetIPodAuthenticationSignature = 0x1D, /* 1.01, from acc, ipod-auth-sig.h */
IAPGeneralCommandID_RetIPodAuthenticationSignature = 0x1E, /* 1.01, from dev, ipod-auth-sig.h */
IAPGeneralCommandID_AckIPodAuthenticationStatus = 0x1F, /* 1.01, from acc, ipod-auth-sig.h */
IAPGeneralCommandID_NotifyIPodStateChange = 0x23, /* 1.02, from dev, notify-ipod-state-change.h */
IAPGeneralCommandID_GetIPodOptions = 0x24, /* 1.05, from acc, no payload */
IAPGeneralCommandID_RetIPodOptions = 0x25, /* 1.05, from dev, ipod-options.h */
IAPGeneralCommandID_GetAccessoryInfo = 0x27, /* 1.04, from dev, acc-info.h */
IAPGeneralCommandID_RetAccessoryInfo = 0x28, /* 1.04, from acc, acc-info.h */
IAPGeneralCommandID_GetIPodPreferences = 0x29, /* 1.05, from acc, ipod-preferences.h */
IAPGeneralCommandID_RetIPodPreferences = 0x2A, /* 1.05, from dev, ipod-preferences.h */
IAPGeneralCommandID_SetIPodPreferences = 0x2B, /* 1.05, from acc, ipod-preferences.h */
IAPGeneralCommandID_GetUIMode = 0x35, /* 1.09, from acc, no payload */
IAPGeneralCommandID_RetUIMode = 0x36, /* 1.09, from dev, ui-mode.h */
IAPGeneralCommandID_SetUIMode = 0x37, /* 1.09, from acc, ui-mode.h */
IAPGeneralCommandID_StartIDPS = 0x38, /* 1.09, from acc, no payload */
IAPGeneralCommandID_SetFIDTokenValues = 0x39, /* 1.09, from acc, fid-token-values.h */
IAPGeneralCommandID_AckFIDTokenValues = 0x3A, /* 1.09, from dev, fid-token-values.h */
IAPGeneralCommandID_EndIDPS = 0x3B, /* 1.09, from acc, end-idps.h */
IAPGeneralCommandID_IDPSStatus = 0x3C, /* 1.09, from dev, end-idps.h */
IAPGeneralCommandID_OpenDataSessionForProtocol = 0x3F, /* 1.09, from dev, data-session.h */
IAPGeneralCommandID_CloseDataSession = 0x40, /* 1.09, from dev, data-session.h */
IAPGeneralCommandID_AccessoryAck = 0x41, /* 1.09, from acc, acc-ack.h */
IAPGeneralCommandID_AccessoryDataTransfer = 0x42, /* 1.09, from acc, data-transfer.h */
IAPGeneralCommandID_IPodDataTransfer = 0x43, /* 1.09, from dev, data-transfer.h */
IAPGeneralCommandID_SetAccessoryStatusNotification = 0x46, /* 1.09, from dev, acc-status-notification.h */
IAPGeneralCommandID_RetAccessoryStatusNotification = 0x47, /* 1.09, from acc, acc-status-notification.h */
IAPGeneralCommandID_AccessoryStatusNotification = 0x48, /* 1.09, from acc, acc-status-notification.h */
IAPGeneralCommandID_SetEventNotification = 0x49, /* 1.09, from acc, event-notification.h */
IAPGeneralCommandID_IPodNotification = 0x4A, /* 1.09, from dev, ipod-notifiction.h */
IAPGeneralCommandID_GetIPodOptionsForLingo = 0x4B, /* 1.09, from acc, ipod-options-for-lingo.h */
IAPGeneralCommandID_RetIPodOptionsForLingo = 0x4C, /* 1.09, from dev, ipod-options-for-lingo.h */
IAPGeneralCommandID_GetEventNotification = 0x4D, /* 1.09, from acc, no payload */
IAPGeneralCommandID_RetEventNotification = 0x4E, /* 1.09, from dev, event-notification.h */
IAPGeneralCommandID_GetSupportedEventNotification = 0x4F, /* 1.09, from acc, no payload */
IAPGeneralCommandID_CancelCommand = 0x50, /* 1.09, from acc, cancel-command.h */
IAPGeneralCommandID_RetSupportedEventNotification = 0x51, /* 1.09, from dev, event-notification.h */
IAPGeneralCommandID_SetAvailableCurrent = 0x54, /* 1.09, from acc, set-available-current.h */
IAPGeneralCommandID_SetInternalBatteryChargingState = 0x56, /* 1.09, from acc, set-internal-battery-charging-state.h */
IAPGeneralCommandID_RequestApplicationLaunch = 0x64, /* 1.09, from acc, request-application-launch.h */
IAPGeneralCommandID_GetNowPlayingApplicationBundleName = 0x65, /* 1.09, from acc, no payload */
IAPGeneralCommandID_RetNowPlayingApplicationBundleName = 0x66, /* 1.09, from dev, now-playing-app-bundle-name.h */
IAPGeneralCommandID_GetLocalizationInfo = 0x67, /* 1.09, from acc, localization-info.h */
IAPGeneralCommandID_RetLocalizationInfo = 0x68, /* 1.09, from dev, localization-info.h */
IAPGeneralCommandID_RequestWiFiConnectionInfo = 0x69, /* 1.09, from acc, no payload */
IAPGeneralCommandID_WiFiConnectionInfo = 0x6A, /* 1.09, from dev, wifi-connection-info.h */
};
#include "general/acc-ack.h"
#include "general/acc-auth-info.h"
#include "general/acc-auth-sig.h"
#include "general/acc-info.h"
#include "general/acc-status-notification.h"
#include "general/cancel-command.h"
#include "general/data-session.h"
#include "general/data-transfer.h"
#include "general/end-idps.h"
#include "general/event-notification.h"
#include "general/extended-interface-mode.h"
#include "general/fid-token-values.h"
#include "general/identify-device-lingoes.h"
#include "general/identify.h"
#include "general/ipod-ack.h"
#include "general/ipod-auth-info.h"
#include "general/ipod-auth-sig.h"
#include "general/ipod-name.h"
#include "general/ipod-notification.h"
#include "general/ipod-options-for-lingo.h"
#include "general/ipod-options.h"
#include "general/ipod-preferences.h"
#include "general/ipod-software-version.h"
#include "general/lingo-protocol-version.h"
#include "general/localization-info.h"
#include "general/now-playing-app-bundle-name.h"
#include "general/request-application-launch.h"
#include "general/set-available-current.h"
#include "general/transport-max-payload-size.h"
#include "general/ui-mode.h"
#include "general/wifi-connection-info.h"

View file

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
struct IAPAccAckPayload {
uint8_t status; /* = IAPAckStatus_{Success,EBadParameter} */
uint8_t id;
} __attribute__((packed));

View file

@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
struct IAPRetAccAuthInfoPayload {
uint8_t protocol_major;
uint8_t protocol_minor;
} __attribute__((packed));
struct IAPRetAccAuthInfoPayload2p0 {
uint8_t protocol_major; /* = 0x02 */
uint8_t protocol_minor; /* = 0x00 */
uint8_t cert_current_section_index;
uint8_t cert_max_section_index;
uint8_t cert_data[];
} __attribute__((packed));
enum IAPAckAccAuthInfoStatus {
IAPAckAccAuthInfoStatus_Supported = 0x00,
IAPAckAccAuthInfoStatus_CertTooLong = 0x04,
IAPAckAccAuthInfoStatus_Unsupported = 0x08,
IAPAckAccAuthInfoStatus_InvalidCert = 0x0A,
IAPAckAccAuthInfoStatus_InvalidCertPerm = 0x0B,
};
struct IAPAckAccAuthInfoPayload {
uint8_t status; /* IAPAckAccAuthInfoStatus */
} __attribute__((packed));

View file

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
struct IAPGetAccAuthSigPayload1p0 {
uint8_t challenge[16];
uint8_t retry;
} __attribute__((packed));
struct IAPGetAccAuthSigPayload2p0 {
uint8_t challenge[20];
uint8_t retry;
} __attribute__((packed));
/*
struct IAPRetAccAuthSigPayload {
uint8_t sig[];
} __attribute__((packed));
*/
struct IAPAckAccAuthSigPayload {
uint8_t status; /* IAPAckStatus */
} __attribute__((packed));

View file

@ -0,0 +1,83 @@
#pragma once
#include <stdint.h>
enum IAPAccInfoType {
IAPAccInfoType_AccInfoCaps = 0x00, /* G1 -> R2 */
IAPAccInfoType_AccName = 0x01, /* G1 -> R1 */
IAPAccInfoType_MinDeviceFirmwareVersion = 0x02, /* G2 -> R3 */
IAPAccInfoType_MinLingoVersion = 0x03, /* G3 -> R4 */
IAPAccInfoType_FirmwareVersion = 0x04, /* G1 -> R5 */
IAPAccInfoType_HardwareVersion = 0x05, /* G1 -> R5 */
IAPAccInfoType_Manufacture = 0x06, /* G1 -> R2 */
IAPAccInfoType_ModelNumber = 0x07, /* G1 -> R2 */
IAPAccInfoType_SerialNumber = 0x08, /* G1 -> R2 */
IAPAccInfoType_MaxPayloadSize = 0x09, /* G1 -> R6 */
IAPAccInfoType_SupportedStatusTypes = 0x0B, /* G1 -> R7 */
};
/* G1 */
struct IAPGetAccInfoPayload {
uint8_t type; /* IAPAccInfoType */
} __attribute__((packed));
/* G2 */
struct IAPGetAccInfoMinDeviceFirmwareVersionPayload {
uint8_t type; /* = IAPAccInfoType_MinDeviceFirmwareVersion */
uint32_t model_id;
} __attribute__((packed));
/* G3 */
struct IAPGetAccInfoMinLingoVersionPayload {
uint8_t type; /* = IAPAccInfoType_MinLingoVersion */
uint8_t lingo_id;
};
/* R1 */
struct IAPRetAccInfoPayload {
uint8_t type; /* IAPAccInfoType */
char value[];
};
/* R2 */
struct IAPRetAccInfoCapsPayload {
uint8_t type; /* = IAPAccInfoType_AccInfoCaps */
uint32_t caps;
} __attribute__((packed));
/* R3 */
struct IAPRetAccInfoMinDeviceFirmwareVersionPayload {
uint8_t type; /* = IAPAccInfoType_MinDeviceFirmwareVersion */
};
/* R4 */
struct IAPRetAccInfoMinLingoVersionPayload {
uint8_t type; /* = IAPAccInfoType_MinLingoVersion */
uint8_t lingo_id;
uint8_t major;
uint8_t minor;
};
/* R5 */
struct IAPRetAccInfoFirmHardVersionPayload {
uint8_t type; /* = IAPAccInfoType_{Firmware,Hardware}Version */
uint8_t major;
uint8_t minor;
uint8_t revision;
} __attribute__((packed));
/* R6 */
struct IAPRetAccInfoMaxPayloadSizePayload {
uint8_t type; /* = IAPAccInfoType_MaxPayloadSize */
uint16_t max_payload_size;
} __attribute__((packed));
enum IAPAccInfoStatusTypes {
IAPAccInfoStatusTypes_Bluetooth = 0b0010,
IAPAccInfoStatusTypes_FaultCondition = 0b0100,
};
/* R7 */
struct IAPRetAccInfoSupportedStatusTypes {
uint8_t type; /* = IAPAccInfoType_SupportedStatusTypes */
uint32_t status_types; /* IAPAccInfoStatusTypes */
} __attribute__((packed));

View file

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
struct IAPSetAccStatusNotificationPayload {
uint32_t mask; /* IAPAccInfoStatusTypes */
} __attribute__((packed));
struct IAPRetAccStatusNotificationPayload {
uint32_t mask; /* IAPAccInfoStatusTypes */
} __attribute__((packed));
struct IAPAccStatusNotificationPayload {
uint32_t type; /* IAPAccInfoStatusTypes */
uint8_t params[];
} __attribute__((packed));
/* [1] P.181 Table 3-108 AccessoryStatusNotification parameters */
/* TODO: add definitions */

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
struct IAPCancelCommandPayload {
uint8_t lingo_id;
uint16_t command_id;
uint16_t transaction_id;
} __attribute__((packed));

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
struct IAPOpenDataSessionForProtocolPayload {
uint16_t session_id;
uint8_t protocol_index;
} __attribute__((packed));
struct IAPCloseDataSessionPayload {
uint16_t session_id;
} __attribute__((packed));

View file

@ -0,0 +1,12 @@
#pragma once
#include <stdint.h>
struct IAPAccDataTransferPayload {
uint16_t session_id;
uint8_t data[];
} __attribute__((packed));
struct IAPIPodDataTransferPayload {
uint16_t session_id;
uint8_t data[];
} __attribute__((packed));

View file

@ -0,0 +1,33 @@
#pragma once
#include <stdint.h>
enum IAPEndIDPSStatus {
IAPEndIDPSStatus_Success = 0x00,
IAPEndIDPSStatus_Reset = 0x01,
IAPEndIDPSStatus_Abort = 0x02,
IAPEndIDPSStatus_AnotherTransport = 0x03,
};
struct IAPEndIDPSPayload {
uint8_t status; /* IAPEndIDPSStatus */
};
enum IAPIDPSStatus {
/* IAPEndIDPSStatus_Success */
IAPIDPSStatus_Success = 0x00,
IAPIDPSStatus_RequiredTokenRejected = 0x01,
IAPIDPSStatus_RequiredTokenMissing = 0x02,
IAPIDPSStatus_RequiredTokenRejectedMissing = 0x03,
/* IAPEndIDPSStatus_Reset */
IAPIDPSStatus_NotTimedOut = 0x04,
IAPIDPSStatus_TimedOut = 0x05,
/* IAPEndIDPSStatus_Abort */
IAPIDPSStatus_Aborted = 0x06,
/* IAPEndIDPSStatus_AnotherTransport */
IAPIDPSStatus_Failed = 0x07,
};
struct IAPIDPSStatusPayload {
uint8_t status; /* IAPIDPSStatus */
};

View file

@ -0,0 +1,31 @@
#pragma once
#include <stdint.h>
/* [1] P.184 Table 3-112 Notification bitmask bits */
enum IAPEventNotificationEvents {
IAPSetEventNotificationEvents_FlowControl = 1 << 2,
IAPSetEventNotificationEvents_RadioTagging = 1 << 3,
IAPSetEventNotificationEvents_Camera = 1 << 4,
IAPSetEventNotificationEvents_ChargingInfo = 1 << 5,
IAPSetEventNotificationEvents_DatabaseChanged = 1 << 9,
IAPSetEventNotificationEvents_AppBundleName = 1 << 10,
IAPSetEventNotificationEvents_SessionSpaceAvail = 1 << 11,
IAPSetEventNotificationEvents_CommandComplete = 1 << 13,
IAPSetEventNotificationEvents_IPodOutMode = 1 << 15,
IAPSetEventNotificationEvents_BluetoothConnection = 1 << 17,
IAPSetEventNotificationEvents_AppDisplayName = 1 << 19,
IAPSetEventNotificationEvents_AssistiveTouch = 1 << 20,
};
struct IAPSetEventNotificationPayload {
uint64_t mask; /* IAPEventNotificationEvents */
} __attribute__((packed));
struct IAPRetEventNotificationPayload {
uint64_t mask; /* IAPEventNotificationEvents */
} __attribute__((packed));
struct IAPRetSupportedEventNotificationPayload {
uint64_t mask; /* IAPEventNotificationEvents */
} __attribute__((packed));

View file

@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
/* [1] P.127 3.3.4 Command 0x04: ReturnExtendedInterfaceMode */
struct IAPReturnExtendedInterfaceModePayload {
uint8_t is_ext_mode;
} __attribute__((packed));

View file

@ -0,0 +1,58 @@
#pragma once
#include <stdint.h>
/* [1] P.161 Table 3-67 FIDTokenValues tokens */
/* = 0x{type}{subtype} */
enum IAPFIDTokenTypes {
IAPFIDTokenTypes_Identify = 0x0000,
IAPFIDTokenTypes_AccCaps = 0x0001,
IAPFIDTokenTypes_AccInfo = 0x0002,
IAPFIDTokenTypes_IPodPreference = 0x0003,
IAPFIDTokenTypes_EAProtocol = 0x0004,
IAPFIDTokenTypes_BundleSeedIDPref = 0x0005,
IAPFIDTokenTypes_ScreenInfo = 0x0007,
IAPFIDTokenTypes_EAProtocolMetadata = 0x0008,
IAPFIDTokenTypes_AccDigitalAudioSampleRates = 0x000E,
IAPFIDTokenTypes_AccDigitalAudioVideoDelay = 0x000F,
IAPFIDTokenTypes_MicrophoneCaps = 0x0100,
};
/* [1] P.161 Table 3-66 FIDTokenValues field format */
struct IAPFIDTokenValuesToken {
uint8_t length;
uint8_t type;
uint8_t subtype;
uint8_t data[];
} __attribute__((packed));
/* [1] P.170 Table 3-86 Acknowledgment status codes */
enum IAPFIDTokenValuesAckStatus {
IAPFIDTokenValuesIdentifyAckStatus_Accepted = 0x00,
IAPFIDTokenValuesIdentifyAckStatus_RequiredFailed = 0x01,
IAPFIDTokenValuesIdentifyAckStatus_OptionalFailed = 0x02,
IAPFIDTokenValuesIdentifyAckStatus_NotSupported = 0x03,
IAPFIDTokenValuesIdentifyAckStatus_LingoBusy = 0x04,
IAPFIDTokenValuesIdentifyAckStatus_MaxConnections = 0x05,
};
#include "fid-token-values/acc-caps.h"
#include "fid-token-values/acc-digital-audio-sample-rates.h"
#include "fid-token-values/acc-digital-audio-video-delay.h"
#include "fid-token-values/acc-info.h"
#include "fid-token-values/bundle-seed-id-pref.h"
#include "fid-token-values/ea-protocol-metadata.h"
#include "fid-token-values/ea-protocol.h"
#include "fid-token-values/identify.h"
#include "fid-token-values/ipod-preference.h"
#include "fid-token-values/microphone-caps.h"
#include "fid-token-values/screen-info.h"
struct IAPSetFIDTokenValuesPayload {
uint8_t num_token_values;
uint8_t data[]; /* packed token values */
};
struct IAPAckFIDTokenValuesPayload {
uint8_t num_token_value_acks;
uint8_t data[]; /* packed token value acks */
};

View file

@ -0,0 +1,31 @@
#pragma once
#include <stdint.h>
/* [1] P.164 Table 3-71 Accessory capabilities bit values */
enum IAPFIDTokenValuesAccCapsBits {
IAPFIDTokenValuesAccCapsBits_LineOut = 1 << 0,
IAPFIDTokenValuesAccCapsBits_LineIn = 1 << 1,
IAPFIDTokenValuesAccCapsBits_VideoOut = 1 << 2,
IAPFIDTokenValuesAccCapsBits_USBAudioOut = 1 << 4,
IAPFIDTokenValuesAccCapsBits_AppsCommunication = 1 << 9,
IAPFIDTokenValuesAccCapsBits_CheckVolume = 1 << 11,
IAPFIDTokenValuesAccCapsBits_VoiceOver = 1 << 17,
IAPFIDTokenValuesAccCapsBits_AsyncPlaybackChange = 1 << 18,
IAPFIDTokenValuesAccCapsBits_MixedResponse = 1 << 19,
IAPFIDTokenValuesAccCapsBits_AudioRoutingSwitch = 1 << 21,
IAPFIDTokenValuesAccCapsBits_AssistiveTouch = 1 << 23,
};
struct IAPFIDTokenValuesAccCapsToken {
uint8_t length; /* = 0x0A */
uint8_t type; /* = 0x00 */
uint8_t subtype; /* = 0x01 */
uint64_t caps_bits; /* IAPFIDTokenValuesAccCapsBits */
} __attribute__((packed));
struct IAPFIDTokenValuesAccCapsAck {
uint8_t length; /* = 0x03 */
uint8_t type; /* = 0x00 */
uint8_t subtype; /* = 0x01 */
uint8_t status; /* IAPFIDTokenValuesAckStatus */
};

View file

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
struct IAPFIDTokenValuesAccDigitalAudioSampleRatesToken {
uint8_t length;
uint8_t type; /* = 0x00 */
uint8_t subtype; /* = 0x0E */
uint32_t sample_rates[];
} __attribute__((packed));
struct IAPFIDTokenValuesAccDigitalAudioSampleRatesAck {
uint8_t length; /* = 0x03 */
uint8_t type; /* = 0x00 */
uint8_t subtype; /* = 0x0E */
uint8_t status; /* IAPFIDTokenValuesAckStatus */
} __attribute__((packed));

Some files were not shown because too many files have changed in this diff Show more