示例#1
0
void connection::handle_read_message_id(const boost::system::error_code& e,
        std::size_t bytes_transferred) {
    if (!e) {
        a::const_buffer b = a::buffer(buffer_);
        const message_id *id = a::buffer_cast<const message_id*>(b);
        cmd_ack(*id);
    }
    else {
        printf("handle_read_message_id error %s\n", e.message().c_str());
    }
}
示例#2
0
void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf)
{
    static bool poweron_pressed = false;
    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;
                    }
                }

                if (buf[4] & 2) /* power on */
                {
                    poweron_pressed = 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);
            }

            /* power on released */
            if (poweron_pressed && len >= 5 && !(buf[4] & 2))
            {
                poweron_pressed = false;
#ifdef HAVE_LINE_REC
                /* Belkin TuneTalk microphone sends power-on press+release
                 * events once authentication sequence is finished,
                 * GetDevCaps command is ignored by the device when it is
                 * sent before power-on release event is received.
                 * XXX: It is unknown if other microphone devices are
                 * sending the power-on events.
                 */
                if (DEVICE_LINGO_SUPPORTED(0x01)) {
                    /* GetDevCaps */
                    IAP_TX_INIT(0x01, 0x07);
                    iap_send_tx();
                }
#endif
            }

            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;
        }
    }
}
示例#3
0
// process command from host
void PS2keyboard::process_command() {
    unsigned char command = 0, b = 0;
    while (keyboard -> read(&command));
    Serial.print("Received keyboard host command 0x");
    Serial.println(command, HEX);
    switch (command) {
        case 0xED: // set/reset LEDs
            cmd_ack();
            keyboard -> read(&b);
            set_led_scrolllock(bitRead(b, 0) == 1);
            set_led_numlock(bitRead(b, 1) == 1);
            set_led_capslock(bitRead(b, 2) == 1);
            break;
        case 0xEE: // echo
            while (keyboard -> write(0xEE) != 0);
            last_sent_byte = 0xEE;
            break;
        case 0xF0: // set scan code set
            cmd_ack();
            keyboard -> read(&b);
            if (b == 0) {
                while (keyboard -> write(scancode_set));
            } else {
                set_scancode_set(b);
            }
            break;
        case 0xF2: // read ID
            cmd_ack();
            break;
        case 0xF3: // set typematic rate/delay
            unsigned char td, tr_a, tr_b;
            cmd_ack();
            keyboard -> read(&b);
            td = b >> 5;
            tr_a = (b & 0x00011000) >> 3;
            tr_b = (b & 0x00000111);
            if (td == 3) set_typematic_delay(1000);
            else if (td == 2) set_typematic_delay(750);
            else if (td == 1) set_typematic_delay(500);
            else set_typematic_delay(250);
            set_typematic_delay((pow(2, tr_a) * (8 + tr_b)) / 240);
            break;
        case 0xF4: // enable
            cmd_ack();
            enabled = true;
            buf_length = 0;
            break;
        case 0xF5: // disable and set defaults (not full BAT)
            cmd_ack();
            set_defaults();
            enabled = false;
            break;
        case 0xF6: // set defaults and reset w/full test
            cmd_ack();
            run_bat();
            break;
        case 0xF7: // SC MODE 3 ONLY: set all keys type typematic
            cmd_ack();
            break;
        case 0xF8: // SC MODE 3 ONLY: set all keys type make/break
            cmd_ack();
            break;
        case 0xF9: // SC MODE 3 ONLY: set all keys type make
            cmd_ack();
            break;
        case 0xFA: // SC MODE 3 ONLY: set all keys type make/break/typematic
            cmd_ack();
            break;
        case 0xFB: // SC MODE 3 ONLY: set key type typematic
            cmd_ack();
            break;
        case 0xFC: // SC MODE 3 ONLY: set key type make/break
            cmd_ack();
            break;
        case 0xFD: // SC MODE 3 ONLY: set key type make
            cmd_ack();
            break;
        case 0xFE: // resend
            while (keyboard -> write(last_sent_byte) != 0);
            break;
        case 0xFF: // reset w/full test
            cmd_ack();
            run_bat();
            break;
        default: // unknown, hmm
            //cmd_ack();
            cmd_resend();
    }
}