mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
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>
This commit is contained in:
parent
500b137308
commit
b170c73f92
21 changed files with 10629 additions and 1125 deletions
278
apps/iap/iap-lingo2.c
Normal file
278
apps/iap/iap-lingo2.c
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 0x02, Simple Remote Lingo
|
||||
*
|
||||
* TODO:
|
||||
* - Fix cmd 0x00 handling, there has to be a more elegant way of doing
|
||||
* this
|
||||
*/
|
||||
|
||||
#include "iap-core.h"
|
||||
#include "iap-lingo.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
#include "audio.h"
|
||||
#include "settings.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)
|
||||
|
||||
static void cmd_ack(const unsigned char cmd, const unsigned char status)
|
||||
{
|
||||
IAP_TX_INIT(0x02, 0x01);
|
||||
IAP_TX_PUT(status);
|
||||
IAP_TX_PUT(cmd);
|
||||
|
||||
iap_send_tx();
|
||||
}
|
||||
|
||||
#define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK)
|
||||
|
||||
void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf)
|
||||
{
|
||||
unsigned int cmd = buf[1];
|
||||
|
||||
/* We expect at least three bytes in the buffer, one for the
|
||||
* lingo, one for the command, and one for the first button
|
||||
* state bits.
|
||||
*/
|
||||
CHECKLEN(3);
|
||||
|
||||
/* Lingo 0x02 must have been negotiated */
|
||||
if (!DEVICE_LINGO_SUPPORTED(0x02)) {
|
||||
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* ContextButtonStatus (0x00)
|
||||
*
|
||||
* Transmit button events from the device to the iPod
|
||||
*
|
||||
* Packet format (offset in buf[]: Description)
|
||||
* 0x00: Lingo ID: Simple Remote Lingo, always 0x02
|
||||
* 0x01: Command, always 0x00
|
||||
* 0x02: Button states 0:7
|
||||
* 0x03: Button states 8:15 (optional)
|
||||
* 0x04: Button states 16:23 (optional)
|
||||
* 0x05: Button states 24:31 (optional)
|
||||
*
|
||||
* Returns: (none)
|
||||
*/
|
||||
case 0x00:
|
||||
{
|
||||
iap_remotebtn = BUTTON_NONE;
|
||||
iap_timeoutbtn = 0;
|
||||
|
||||
if(buf[2] != 0)
|
||||
{
|
||||
if(buf[2] & 1)
|
||||
REMOTE_BUTTON(BUTTON_RC_PLAY);
|
||||
if(buf[2] & 2)
|
||||
REMOTE_BUTTON(BUTTON_RC_VOL_UP);
|
||||
if(buf[2] & 4)
|
||||
REMOTE_BUTTON(BUTTON_RC_VOL_DOWN);
|
||||
if(buf[2] & 8)
|
||||
REMOTE_BUTTON(BUTTON_RC_RIGHT);
|
||||
if(buf[2] & 16)
|
||||
REMOTE_BUTTON(BUTTON_RC_LEFT);
|
||||
}
|
||||
else if(len >= 4 && buf[3] != 0)
|
||||
{
|
||||
if(buf[3] & 1) /* play */
|
||||
{
|
||||
if (audio_status() != AUDIO_STATUS_PLAY)
|
||||
REMOTE_BUTTON(BUTTON_RC_PLAY);
|
||||
}
|
||||
if(buf[3] & 2) /* pause */
|
||||
{
|
||||
if (audio_status() == AUDIO_STATUS_PLAY)
|
||||
REMOTE_BUTTON(BUTTON_RC_PLAY);
|
||||
}
|
||||
if(buf[3] & 128) /* Shuffle */
|
||||
{
|
||||
if (!iap_btnshuffle)
|
||||
{
|
||||
iap_shuffle_state(!global_settings.playlist_shuffle);
|
||||
iap_btnshuffle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(len >= 5 && buf[4] != 0)
|
||||
{
|
||||
if(buf[4] & 1) /* repeat */
|
||||
{
|
||||
if (!iap_btnrepeat)
|
||||
{
|
||||
iap_repeat_next();
|
||||
iap_btnrepeat = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Power off
|
||||
* Not quite sure how to react to this, but stopping playback
|
||||
* is a good start.
|
||||
*/
|
||||
if (buf[4] & 0x04)
|
||||
{
|
||||
if (audio_status() == AUDIO_STATUS_PLAY)
|
||||
REMOTE_BUTTON(BUTTON_RC_PLAY);
|
||||
}
|
||||
|
||||
if(buf[4] & 16) /* ffwd */
|
||||
REMOTE_BUTTON(BUTTON_RC_RIGHT);
|
||||
if(buf[4] & 32) /* frwd */
|
||||
REMOTE_BUTTON(BUTTON_RC_LEFT);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
/* ACK (0x01)
|
||||
*
|
||||
* Sent from the iPod to the device
|
||||
*/
|
||||
|
||||
/* ImageButtonStatus (0x02)
|
||||
*
|
||||
* Transmit image button events from the device to the iPod
|
||||
*
|
||||
* Packet format (offset in buf[]: Description)
|
||||
* 0x00: Lingo ID: Simple Remote Lingo, always 0x02
|
||||
* 0x01: Command, always 0x02
|
||||
* 0x02: Button states 0:7
|
||||
* 0x03: Button states 8:15 (optional)
|
||||
* 0x04: Button states 16:23 (optional)
|
||||
* 0x05: Button states 24:31 (optional)
|
||||
*
|
||||
* This command requires authentication
|
||||
*
|
||||
* Returns on success:
|
||||
* IAP_ACK_OK
|
||||
*
|
||||
* Returns on failure:
|
||||
* IAP_ACK_*
|
||||
*/
|
||||
case 0x02:
|
||||
{
|
||||
if (!DEVICE_AUTHENTICATED) {
|
||||
cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
|
||||
break;
|
||||
}
|
||||
|
||||
cmd_ack(cmd, IAP_ACK_CMD_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* VideoButtonStatus (0x03)
|
||||
*
|
||||
* Transmit video button events from the device to the iPod
|
||||
*
|
||||
* Packet format (offset in buf[]: Description)
|
||||
* 0x00: Lingo ID: Simple Remote Lingo, always 0x02
|
||||
* 0x01: Command, always 0x03
|
||||
* 0x02: Button states 0:7
|
||||
* 0x03: Button states 8:15 (optional)
|
||||
* 0x04: Button states 16:23 (optional)
|
||||
* 0x05: Button states 24:31 (optional)
|
||||
*
|
||||
* This command requires authentication
|
||||
*
|
||||
* Returns on success:
|
||||
* IAP_ACK_OK
|
||||
*
|
||||
* Returns on failure:
|
||||
* IAP_ACK_*
|
||||
*/
|
||||
case 0x03:
|
||||
{
|
||||
if (!DEVICE_AUTHENTICATED) {
|
||||
cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
|
||||
break;
|
||||
}
|
||||
|
||||
cmd_ack(cmd, IAP_ACK_CMD_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* AudioButtonStatus (0x04)
|
||||
*
|
||||
* Transmit audio button events from the device to the iPod
|
||||
*
|
||||
* Packet format (offset in buf[]: Description)
|
||||
* 0x00: Lingo ID: Simple Remote Lingo, always 0x02
|
||||
* 0x01: Command, always 0x04
|
||||
* 0x02: Button states 0:7
|
||||
* 0x03: Button states 8:15 (optional)
|
||||
* 0x04: Button states 16:23 (optional)
|
||||
* 0x05: Button states 24:31 (optional)
|
||||
*
|
||||
* This command requires authentication
|
||||
*
|
||||
* Returns on success:
|
||||
* IAP_ACK_OK
|
||||
*
|
||||
* Returns on failure:
|
||||
* IAP_ACK_*
|
||||
*/
|
||||
case 0x04:
|
||||
{
|
||||
unsigned char repeatbuf[6];
|
||||
|
||||
if (!DEVICE_AUTHENTICATED) {
|
||||
cmd_ack(cmd, IAP_ACK_NO_AUTHEN);
|
||||
break;
|
||||
}
|
||||
|
||||
/* This is basically the same command as ContextButtonStatus (0x00),
|
||||
* with the difference that it requires authentication and that
|
||||
* it returns an ACK packet to the device.
|
||||
* So just route it through the handler again, with 0x00 as the
|
||||
* command
|
||||
*/
|
||||
memcpy(repeatbuf, buf, 6);
|
||||
repeatbuf[1] = 0x00;
|
||||
iap_handlepkt_mode2((len<6)?len:6, repeatbuf);
|
||||
|
||||
cmd_ok(cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The default response is IAP_ACK_BAD_PARAM */
|
||||
default:
|
||||
{
|
||||
#ifdef LOGF_ENABLE
|
||||
logf("iap: Unsupported Mode02 Command");
|
||||
#else
|
||||
cmd_ack(cmd, IAP_ACK_BAD_PARAM);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue