summaryrefslogtreecommitdiff
path: root/apps/iap/iap-core.h
diff options
context:
space:
mode:
authorRalf Ertzinger <rockbox@camperquake.de>2013-06-22 10:08:23 +0100
committerFrank Gevaerts <frank@gevaerts.be>2013-11-10 18:41:24 +0100
commitb170c73f922e3457b923b4e7fcbec794a8885c77 (patch)
tree89fbdbd8c25af5101a29a1ede3b896332a4e205c /apps/iap/iap-core.h
parent500b137308a6ee5c2aba873734a8956d70472f56 (diff)
downloadrockbox-b170c73f922e3457b923b4e7fcbec794a8885c77.tar.gz
rockbox-b170c73f922e3457b923b4e7fcbec794a8885c77.zip
Updated IAP commands.
Originally written and uploaded by Lalufu (Ralf Ertzinger) in Feb 2012. They have been condensed into a single patch and some further additions by Andy Potter. Currently includes Authentication V2 support from iPod to Accessory, RF/BlueTooth transmitter support, selecting a playlist and selecting a track from the current playlist. Does not support uploading Album Art or podcasts. Has been tested on the following iPods, 4th Gen Grayscale, 4th Gen Color/Photo, Mini 2nd Gen, Nano 1st Gen and Video 5.5Gen. Change-Id: Ie8fc098361844132f0228ecbe3c48da948726f5e Co-Authored by: Andy Potter <liveboxandy@gmail.com> Reviewed-on: http://gerrit.rockbox.org/533 Reviewed-by: Frank Gevaerts <frank@gevaerts.be>
Diffstat (limited to 'apps/iap/iap-core.h')
-rw-r--r--apps/iap/iap-core.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/apps/iap/iap-core.h b/apps/iap/iap-core.h
new file mode 100644
index 0000000000..d06e3c300c
--- /dev/null
+++ b/apps/iap/iap-core.h
@@ -0,0 +1,250 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr & Nick Robinson
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef _IAP_CORE_H
20#define _IAP_CORE_H
21
22#include <stdint.h>
23#include <string.h>
24#include "timefuncs.h"
25#include "metadata.h"
26#include "playlist.h"
27#include "iap.h"
28
29#define LOGF_ENABLE
30/* #undef LOGF_ENABLE */
31#ifdef LOGF_ENABLE
32 #include "logf.h"
33#endif
34
35/* The Model ID of the iPod we emulate. Currently a 160GB classic */
36#define IAP_IPOD_MODEL (0x00130200U)
37
38/* The firmware version we emulate. Currently 2.0.3 */
39#define IAP_IPOD_FIRMWARE_MAJOR (2)
40#define IAP_IPOD_FIRMWARE_MINOR (0)
41#define IAP_IPOD_FIRMWARE_REV (3)
42
43/* Status code for IAP ack messages */
44#define IAP_ACK_OK (0x00) /* Success */
45#define IAP_ACK_UNKNOWN_DB (0x01) /* Unknown Database Category */
46#define IAP_ACK_CMD_FAILED (0x02) /* Command failed */
47#define IAP_ACK_NO_RESOURCE (0x03) /* Out of resources */
48#define IAP_ACK_BAD_PARAM (0x04) /* Bad parameter */
49#define IAP_ACK_UNKNOWN_ID (0x05) /* Unknown ID */
50#define IAP_ACK_PENDING (0x06) /* Command pending */
51#define IAP_ACK_NO_AUTHEN (0x07) /* Not authenticated */
52#define IAP_ACK_BAD_AUTHEN (0x08) /* Bad authentication version */
53/* 0x09 reserved */
54#define IAP_ACK_CERT_INVAL (0x0A) /* Certificate invalid */
55#define IAP_ACK_CERT_PERM (0x0B) /* Certificate permissions invalid */
56/* 0x0C-0x10 reserved */
57#define IAP_ACK_RES_INVAL (0x11) /* Invalid accessory resistor value */
58
59/* Add a button to the remote button bitfield. Also set iap_repeatbtn=1
60 * to ensure a button press is at least delivered once.
61 */
62#define REMOTE_BUTTON(x) do { \
63 iap_remotebtn |= (x); \
64 iap_timeoutbtn = 3; \
65 iap_repeatbtn = 2; \
66 } while(0)
67
68/* States of the extended command support */
69enum interface_state {
70 IST_STANDARD, /* General state, support lingo 0x00 commands */
71 IST_EXTENDED, /* Extended Interface lingo (0x04) negotiated */
72};
73
74/* States of the authentication state machine */
75enum authen_state {
76 AUST_NONE, /* Initial state, no message sent */
77 AUST_INIT, /* Remote side has requested authentication */
78 AUST_CERTREQ, /* Remote certificate requested */
79 AUST_CERTBEG, /* Certificate is being received */
80 AUST_CERTDONE, /* Certificate received */
81 AUST_CHASENT, /* Challenge sent */
82 AUST_CHADONE, /* Challenge response received */
83 AUST_AUTH, /* Authentication complete */
84};
85
86/* State of authentication */
87struct auth_t {
88 enum authen_state state; /* Current state of authentication */
89 unsigned char max_section; /* The maximum number of certificate sections */
90 unsigned char next_section; /* The next expected section number */
91};
92
93/* State of GetAccessoryInfo */
94enum accinfo_state {
95 ACCST_NONE, /* Initial state, no message sent */
96 ACCST_INIT, /* Send out initial GetAccessoryInfo */
97 ACCST_SENT, /* Wait for initial RetAccessoryInfo */
98 ACCST_DATA, /* Query device information, according to capabilities */
99};
100
101/* A struct describing an attached device and it's current
102 * state
103 */
104struct device_t {
105 struct auth_t auth; /* Authentication state */
106 enum accinfo_state accinfo; /* Accessory information state */
107 uint32_t lingoes; /* Negotiated lingoes */
108 uint32_t notifications; /* Requested notifications. These are just the
109 * notifications explicitly requested by the
110 * device
111 */
112 uint32_t changed_notifications; /* Tracks notifications that changed since the last
113 * call to SetRemoteEventNotification or GetRemoteEventStatus
114 */
115 bool do_notify; /* Notifications enabled */
116 bool do_power_notify; /* Whether to send power change notifications.
117 * These are sent automatically to all devices
118 * that used IdentifyDeviceLingoes to identify
119 * themselves, independent of other notifications
120 */
121
122 uint32_t trackpos_ms; /* These fields are to save the current state */
123 uint32_t track_index; /* of various fields so we can send a notification */
124 uint32_t chapter_index; /* if they change */
125 unsigned char play_status;
126 bool mute;
127 unsigned char volume;
128 unsigned char power_state;
129 unsigned char battery_level;
130 uint32_t equalizer_index;
131 unsigned char shuffle;
132 unsigned char repeat;
133 struct tm datetime;
134 unsigned char alarm_state;
135 unsigned char alarm_hour;
136 unsigned char alarm_minute;
137 unsigned char backlight;
138 bool hold;
139 unsigned char soundcheck;
140 unsigned char audiobook;
141 uint16_t trackpos_s;
142 uint32_t capabilities; /* Capabilities of the device, as returned by type 0
143 * of GetAccessoryInfo
144 */
145 uint32_t capabilities_queried; /* Capabilities already queried */
146};
147
148extern struct device_t device;
149#define DEVICE_AUTHENTICATED (device.auth.state == AUST_AUTH)
150#define DEVICE_AUTH_RUNNING ((device.auth.state != AUST_NONE) && (device.auth.state != AUST_AUTH))
151#define DEVICE_LINGO_SUPPORTED(x) (device.lingoes & BIT_N((x)&0x1f))
152
153extern unsigned long iap_remotebtn;
154extern unsigned int iap_timeoutbtn;
155extern int iap_repeatbtn;
156
157extern unsigned char* iap_txpayload;
158extern unsigned char* iap_txnext;
159
160/* These are a number of helper macros to manage the dynamic TX buffer content
161 * These macros DO NOT CHECK for buffer overflow. iap_send_tx() will, but
162 * it might be too late at that point. See the current size of TX_BUFLEN
163 */
164
165/* Initialize the TX buffer with a lingo and command ID. This will reset the
166 * data pointer, effectively invalidating unsent information in the TX buffer.
167 * There are two versions of this, one for 1 byte command IDs (all Lingoes except
168 * 0x04) and one for two byte command IDs (Lingo 0x04)
169 */
170#define IAP_TX_INIT(lingo, command) do { \
171 iap_txnext = iap_txpayload; \
172 IAP_TX_PUT((lingo)); \
173 IAP_TX_PUT((command)); \
174 } while (0)
175
176#define IAP_TX_INIT4(lingo, command) do { \
177 iap_txnext = iap_txpayload; \
178 IAP_TX_PUT((lingo)); \
179 IAP_TX_PUT_U16((command)); \
180 } while (0)
181
182/* Put an unsigned char into the TX buffer */
183#define IAP_TX_PUT(data) *(iap_txnext++) = (data)
184
185/* Put a 16bit unsigned quantity into the TX buffer */
186#define IAP_TX_PUT_U16(data) do { \
187 put_u16(iap_txnext, (data)); \
188 iap_txnext += 2; \
189 } while (0)
190
191/* Put a 32bit unsigned quantity into the TX buffer */
192#define IAP_TX_PUT_U32(data) do { \
193 put_u32(iap_txnext, (data)); \
194 iap_txnext += 4; \
195 } while (0)
196
197/* Put an arbitrary amount of data (identified by a char pointer and
198 * a length) into the TX buffer
199 */
200#define IAP_TX_PUT_DATA(data, len) do { \
201 memcpy(iap_txnext, (unsigned char *)(data), (len)); \
202 iap_txnext += (len); \
203 } while(0)
204
205/* Put a NULL terminated string into the TX buffer, including the
206 * NULL byte
207 */
208#define IAP_TX_PUT_STRING(str) IAP_TX_PUT_DATA((str), strlen((str))+1)
209
210/* Put a NULL terminated string into the TX buffer, taking care not to
211 * overflow the buffer. If the string does not fit into the TX buffer
212 * it will be truncated, but always NULL terminated.
213 *
214 * This function is expensive compared to the other IAP_TX_PUT_*
215 * functions
216 */
217#define IAP_TX_PUT_STRLCPY(str) iap_tx_strlcpy(str)
218
219extern unsigned char lingo_versions[32][2];
220#define LINGO_SUPPORTED(x) (LINGO_MAJOR((x)&0x1f) > 0)
221#define LINGO_MAJOR(x) (lingo_versions[(x)&0x1f][0])
222#define LINGO_MINOR(x) (lingo_versions[(x)&0x1f][1])
223
224void put_u16(unsigned char *buf, const uint16_t data);
225void put_u32(unsigned char *buf, const uint32_t data);
226uint32_t get_u32(const unsigned char *buf);
227uint16_t get_u16(const unsigned char *buf);
228void iap_tx_strlcpy(const unsigned char *str);
229
230void iap_reset_auth(struct auth_t* auth);
231void iap_reset_device(struct device_t* device);
232
233void iap_shuffle_state(bool state);
234void iap_repeat_state(unsigned char state);
235void iap_repeat_next(void);
236void iap_fill_power_state(void);
237
238void iap_send_tx(void);
239
240extern enum interface_state interface_state;
241void iap_interface_state_change(const enum interface_state new);
242
243extern bool iap_btnrepeat;
244extern bool iap_btnshuffle;
245
246uint32_t iap_get_trackpos(void);
247uint32_t iap_get_trackindex(void);
248void iap_get_trackinfo(const unsigned int track, struct mp3entry* id3);
249
250#endif