1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Alan Korr & Nick Robinson
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/* Lingo 0x01: Microphone Lingo
*/
#include "iap-core.h"
#include "iap-lingo.h"
/*
* This macro is meant to be used inside an IAP mode message handler.
* It is passed the expected minimum length of the message buffer.
* If the buffer does not have the required lenght an ACK
* packet with a Bad Parameter error is generated.
*/
#define CHECKLEN(x) do { \
if (len < (x)) { \
cmd_ack(cmd, IAP_ACK_BAD_PARAM); \
return; \
}} while(0)
/* Check for authenticated state, and return an ACK Not
* Authenticated on failure.
*/
#define CHECKAUTH do { \
if (!DEVICE_AUTHENTICATED) { \
cmd_ack(cmd, IAP_ACK_NO_AUTHEN); \
return; \
}} while(0)
static void cmd_ack(const unsigned char cmd, const unsigned char status)
{
IAP_TX_INIT(0x03, 0x00);
IAP_TX_PUT(status);
IAP_TX_PUT(cmd);
iap_send_tx();
}
/* returns record status */
bool iap_record(bool onoff)
{
if (!DEVICE_LINGO_SUPPORTED(0x01))
return false;
/* iPodModeChange */
IAP_TX_INIT(0x01, 0x06);
IAP_TX_PUT(onoff ? 0x00 : 0x01);
iap_send_tx();
return onoff;
}
void iap_handlepkt_mode1(const unsigned int len, const unsigned char *buf)
{
unsigned int cmd = buf[1];
/* Lingo 0x04 commands are at least 4 bytes in length */
CHECKLEN(4);
/* Lingo 0x01 must have been negotiated */
if (!DEVICE_LINGO_SUPPORTED(0x01)) {
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
return;
}
/* Authentication required for all commands */
CHECKAUTH;
switch (cmd)
{
/* BeginRecord (0x00) Deprecated
*
* Sent from the iPod to the device
*/
/* EndRecord (0x01) Deprecated
*
* Sent from the iPod to the device
*/
/* BeginPlayback (0x02) Deprecated
*
* Sent from the iPod to the device
*/
/* EndPlayback (0x03) Deprecated
*
* Sent from the iPod to the device
*/
/* ACK (0x04)
*
* The device sends an ACK response when a command
* that does not return any data has completed.
*
* Packet format (offset in buf[]: Description)
* 0x00: Lingo ID: Microphone Lingo, always 0x01
* 0x01: Command, always 0x04
* 0x02: The command result status
* 0x03: The ID of the command for which the
* response is being sent
*
* Returns: (none)
*/
case 0x04:
#ifdef LOGF_ENABLE
if (buf[2] != 0x00)
logf("iap: Mode1 Command ACK error: "
"0x%02x 0x%02x", buf[2], buf[3]);
#endif
break;
/* GetDevAck (0x05)
*
* Sent from the iPod to the device
*/
/* iPodModeChange (0x06)
*
* Sent from the iPod to the device
*/
/* GetDevCaps (0x07)
*
* Sent from the iPod to the device
*/
/* RetDevCaps (0x08)
*
* The microphone device returns the payload
* indicating which capabilities it supports.
*
* Packet format (offset in buf[]: Description)
* 0x00: Lingo ID: Microphone Lingo, always 0x01
* 0x01: Command, always 0x08
* 0x02: Device capabilities (bits 31:24)
* 0x03: Device capabilities (bits 23:16)
* 0x04: Device capabilities (bits 15:8)
* 0x05: Device capabilities (bits 7:0)
*
* Returns:
* SetDevCtrl, sets stereo line input when supported
*/
case 0x08:
CHECKLEN(6);
if ((buf[5] & 3) == 3) {
/* SetDevCtrl, set stereo line-in */
IAP_TX_INIT(0x01, 0x0B);
IAP_TX_PUT(0x01);
IAP_TX_PUT(0x01);
iap_send_tx();
}
/* TODO?: configure recording level/limiter controls
when supported by the device */
break;
/* GetDevCtrl (0x09)
*
* Sent from the iPod to the device
*/
/* RetDevCaps (0x0A)
*
* The device returns the current control state
* for the specified control type.
*
* Packet format (offset in buf[]: Description)
* 0x00: Lingo ID: Microphone Lingo, always 0x01
* 0x01: Command, always 0x0A
* 0x02: The control type
* 0x03: The control data
*/
case 0x0A:
switch (buf[2])
{
case 0x01: /* stereo/mono line-in control */
case 0x02: /* recording level control */
case 0x03: /* recording level limiter control */
break;
}
break;
/* SetDevCtrl (0x0B)
*
* Sent from the iPod to the device
*/
/* The default response is IAP_ACK_BAD_PARAM */
default:
{
#ifdef LOGF_ENABLE
logf("iap: Unsupported Mode1 Command");
#endif
break;
}
}
}
|