summaryrefslogtreecommitdiff
path: root/apps/iap/iap-lingo2.c
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-lingo2.c
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-lingo2.c')
-rw-r--r--apps/iap/iap-lingo2.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/apps/iap/iap-lingo2.c b/apps/iap/iap-lingo2.c
new file mode 100644
index 0000000000..4fbf730192
--- /dev/null
+++ b/apps/iap/iap-lingo2.c
@@ -0,0 +1,278 @@
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
20/* Lingo 0x02, Simple Remote Lingo
21 *
22 * TODO:
23 * - Fix cmd 0x00 handling, there has to be a more elegant way of doing
24 * this
25 */
26
27#include "iap-core.h"
28#include "iap-lingo.h"
29#include "system.h"
30#include "button.h"
31#include "audio.h"
32#include "settings.h"
33
34/*
35 * This macro is meant to be used inside an IAP mode message handler.
36 * It is passed the expected minimum length of the message buffer.
37 * If the buffer does not have the required lenght an ACK
38 * packet with a Bad Parameter error is generated.
39 */
40#define CHECKLEN(x) do { \
41 if (len < (x)) { \
42 cmd_ack(cmd, IAP_ACK_BAD_PARAM); \
43 return; \
44 }} while(0)
45
46static void cmd_ack(const unsigned char cmd, const unsigned char status)
47{
48 IAP_TX_INIT(0x02, 0x01);
49 IAP_TX_PUT(status);
50 IAP_TX_PUT(cmd);
51
52 iap_send_tx();
53}
54
55#define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK)
56
57void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf)
58{
59 unsigned int cmd = buf[1];
60
61 /* We expect at least three bytes in the buffer, one for the
62 * lingo, one for the command, and one for the first button
63 * state bits.
64 */
65 CHECKLEN(3);
66
67 /* Lingo 0x02 must have been negotiated */
68 if (!DEVICE_LINGO_SUPPORTED(0x02)) {
69 cmd_ack(cmd, IAP_ACK_BAD_PARAM);
70 return;
71 }
72
73 switch (cmd)
74 {
75 /* ContextButtonStatus (0x00)
76 *
77 * Transmit button events from the device to the iPod
78 *
79 * Packet format (offset in buf[]: Description)
80 * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
81 * 0x01: Command, always 0x00
82 * 0x02: Button states 0:7
83 * 0x03: Button states 8:15 (optional)
84 * 0x04: Button states 16:23 (optional)
85 * 0x05: Button states 24:31 (optional)
86 *
87 * Returns: (none)
88 */
89 case 0x00:
90 {
91 iap_remotebtn = BUTTON_NONE;
92 iap_timeoutbtn = 0;
93
94 if(buf[2] != 0)
95 {
96 if(buf[2] & 1)
97 REMOTE_BUTTON(BUTTON_RC_PLAY);
98 if(buf[2] & 2)
99 REMOTE_BUTTON(BUTTON_RC_VOL_UP);
100 if(buf[2] & 4)
101 REMOTE_BUTTON(BUTTON_RC_VOL_DOWN);
102 if(buf[2] & 8)
103 REMOTE_BUTTON(BUTTON_RC_RIGHT);
104 if(buf[2] & 16)
105 REMOTE_BUTTON(BUTTON_RC_LEFT);
106 }
107 else if(len >= 4 && buf[3] != 0)
108 {
109 if(buf[3] & 1) /* play */
110 {
111 if (audio_status() != AUDIO_STATUS_PLAY)
112 REMOTE_BUTTON(BUTTON_RC_PLAY);
113 }
114 if(buf[3] & 2) /* pause */
115 {
116 if (audio_status() == AUDIO_STATUS_PLAY)
117 REMOTE_BUTTON(BUTTON_RC_PLAY);
118 }
119 if(buf[3] & 128) /* Shuffle */
120 {
121 if (!iap_btnshuffle)
122 {
123 iap_shuffle_state(!global_settings.playlist_shuffle);
124 iap_btnshuffle = true;
125 }
126 }
127 }
128 else if(len >= 5 && buf[4] != 0)
129 {
130 if(buf[4] & 1) /* repeat */
131 {
132 if (!iap_btnrepeat)
133 {
134 iap_repeat_next();
135 iap_btnrepeat = true;
136 }
137 }
138
139 /* Power off
140 * Not quite sure how to react to this, but stopping playback
141 * is a good start.
142 */
143 if (buf[4] & 0x04)
144 {
145 if (audio_status() == AUDIO_STATUS_PLAY)
146 REMOTE_BUTTON(BUTTON_RC_PLAY);
147 }
148
149 if(buf[4] & 16) /* ffwd */
150 REMOTE_BUTTON(BUTTON_RC_RIGHT);
151 if(buf[4] & 32) /* frwd */
152 REMOTE_BUTTON(BUTTON_RC_LEFT);
153 }
154
155 break;
156 }
157 /* ACK (0x01)
158 *
159 * Sent from the iPod to the device
160 */
161
162 /* ImageButtonStatus (0x02)
163 *
164 * Transmit image button events from the device to the iPod
165 *
166 * Packet format (offset in buf[]: Description)
167 * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
168 * 0x01: Command, always 0x02
169 * 0x02: Button states 0:7
170 * 0x03: Button states 8:15 (optional)
171 * 0x04: Button states 16:23 (optional)
172 * 0x05: Button states 24:31 (optional)
173 *
174 * This command requires authentication
175 *
176 * Returns on success:
177 * IAP_ACK_OK
178 *
179 * Returns on failure:
180 * IAP_ACK_*
181 */
182 case 0x02:
183 {
184 if (!DEVICE_AUTHENTICATED) {
185 cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
186 break;
187 }
188
189 cmd_ack(cmd, IAP_ACK_CMD_FAILED);
190 break;
191 }
192
193 /* VideoButtonStatus (0x03)
194 *
195 * Transmit video button events from the device to the iPod
196 *
197 * Packet format (offset in buf[]: Description)
198 * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
199 * 0x01: Command, always 0x03
200 * 0x02: Button states 0:7
201 * 0x03: Button states 8:15 (optional)
202 * 0x04: Button states 16:23 (optional)
203 * 0x05: Button states 24:31 (optional)
204 *
205 * This command requires authentication
206 *
207 * Returns on success:
208 * IAP_ACK_OK
209 *
210 * Returns on failure:
211 * IAP_ACK_*
212 */
213 case 0x03:
214 {
215 if (!DEVICE_AUTHENTICATED) {
216 cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
217 break;
218 }
219
220 cmd_ack(cmd, IAP_ACK_CMD_FAILED);
221 break;
222 }
223
224 /* AudioButtonStatus (0x04)
225 *
226 * Transmit audio button events from the device to the iPod
227 *
228 * Packet format (offset in buf[]: Description)
229 * 0x00: Lingo ID: Simple Remote Lingo, always 0x02
230 * 0x01: Command, always 0x04
231 * 0x02: Button states 0:7
232 * 0x03: Button states 8:15 (optional)
233 * 0x04: Button states 16:23 (optional)
234 * 0x05: Button states 24:31 (optional)
235 *
236 * This command requires authentication
237 *
238 * Returns on success:
239 * IAP_ACK_OK
240 *
241 * Returns on failure:
242 * IAP_ACK_*
243 */
244 case 0x04:
245 {
246 unsigned char repeatbuf[6];
247
248 if (!DEVICE_AUTHENTICATED) {
249 cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
250 break;
251 }
252
253 /* This is basically the same command as ContextButtonStatus (0x00),
254 * with the difference that it requires authentication and that
255 * it returns an ACK packet to the device.
256 * So just route it through the handler again, with 0x00 as the
257 * command
258 */
259 memcpy(repeatbuf, buf, 6);
260 repeatbuf[1] = 0x00;
261 iap_handlepkt_mode2((len<6)?len:6, repeatbuf);
262
263 cmd_ok(cmd);
264 break;
265 }
266
267 /* The default response is IAP_ACK_BAD_PARAM */
268 default:
269 {
270#ifdef LOGF_ENABLE
271 logf("iap: Unsupported Mode02 Command");
272#else
273 cmd_ack(cmd, IAP_ACK_BAD_PARAM);
274#endif
275 break;
276 }
277 }
278}