6

I am trying to send keystrokes via bluetooth to my iPhone4 from ubuntu. I.e., developing a very primitive virtual keyboard.

Problem Have my application talk to iPhone (i.e. using report protocol, that's all iPhone supports). As it is, my write(interruptChannelFD) calls return no errors, but no text appears on iPhone side. The l2cap channels have been opened using blueZ library.

Question 1: Given that no virtual keyboard exists that does that, just how hard is it?

I am at the stage where iPhone and my linux box connect and stay connected, no problem. Also, all the perror() calls are telling me that control and interrupt channel sockets connect just fine. (What I do is hciconfig my dongle to Keyboard device class and use the well-known code by Collin Mulliner with slight modification -- I had to enter a passcode once, as all smartphones require).

Question 2: I should be able to just write() into interrupt socket without worrying about encryption, right? I've entered the passcode and the phone trusts the keyboard. (Collin was pondering a possible hid attack, but I connect honestly)

Also, it is my understanding that in boot protocol of a HID device, the exact report descriptor specfied in SPD is hardly relevant -- the report format is fixed anyway. So...

Question 3: Do I miss something major about the report protocol. What I do is modify the Apple keyboard report descriptor and write into the socket (see below).

const uint8_t hid_spec[] = { 
    0x05, 0x01, // usage page
    0x09, 0x06, // keyboard
    0xa1, 0x01, // collection (Application)
    0x85, 0x01, // report id (0x01)
    0x05, 0x07, // usage page(keyboard)
    0x19, 0xe0, // usage min
    0x29, 0xe7, // usage max
    0x15, 0x00, // logical min
    0x25, 0x01, // logical max
    0x75, 0x01, // report size
    0x95, 0x08, // report count
    0x81, 0x02, // input (dat var abs)

    0x75, 0x08, // report size 
    0x95, 0x01, // report count 
    0x81, 0x01, // input (const)

            // The following two outputs I don't seem to receive
    0x75, 0x01, // report size
    0x95, 0x05, // report count
    0x05, 0x08, // usage page (LEDs)
    0x19, 0x01, // usage min
    0x29, 0x05, // usage max 
    0x91, 0x02, // OUTPUT1 (dat var abs) 

    0x75, 0x03,
    0x95, 0x01,
    0x91, 0x01, // OUTPUT2 (arr,const) 

    0x75, 0x08, // report size
    0x95, 0x06, // report count
    0x15, 0x00, // logical min
    0x26, 0xff, 0x00 // logical max

    0x05, 0x07
    0x19, 0x00
    0x2a, 0xff, 0x00,
    0x81, 0x00,

            // A total of 9 bits sent by now
            // I tried remove the following fields
            /********** BEGIN SNIP
    0x75, 0x01,
    0x95, 0x01,
    0x15, 0x00,
    0x25, 0x01,

    0x05, 0x0c,
    0x09, 0xb8,
    0x81, 0x06,


    0x09, 0xe2,
    0x81, 0x06,


    0x09, 0xe9,
    0x81, 0x02,
    0x09, 0xea,
    0x81, 0x02,
    0x75, 0x01,
    0x95, 0x04,
    0x81, 0x01,
            **** END SNIP/

    0xc0         // end coll

};

After this, I write the following 10 bytes into the interrupt channel:

                    pkg[0] = 0xa1;   // BT HDR (DATA)
                    pkg[1] = 0x01;   // REPORT ID 0x1 == kbd
                    pkg[2] = modifiers; // Ctrl, Shift, etc
                    pkg[3] = 0x00;    // constant 0 (see descr)
                    // pkg[4] = 0x00; // the key code - entered before this point, according to HID usage tables.
                    pkg[5] = 0x00;
                    pkg[6] = 0x00;
                    pkg[7] = 0x00;
                    pkg[8] = 0x00;
                    pkg[9] = 0x00;

                    if (write(is, pkg, 10) <= 0) {
                        perror("write");
                        exit(-1);
                    }
4

1 回答 1

3

美好的一天,先生。

让我向您指出我的一个不起眼的假期浪费时间,它实际上可以与一块名为 iPad 的垃圾一起使用,它的软件堆栈应该与您的 iPhone 相当接近:https ://github.com/lkundrak/ virtkbd

除了实际的实现,我会尽量回答你的问题。

问题一:

鉴于蓝牙 HID 配置文件规范的质量和长度、USB HID 一和可用工具以及实际设备细节,我想反复试验会让您走得更远。拥有一个真正的蓝牙键盘,并编写一个简单的协议中继器和转储器,让您观察它们在做什么——请参阅文档以解密正在发生的事情。

问题2:

正确的。对于我的 iPad,我首先需要将设备与属于键盘类的计算机配对(我的猜测是 iPad 会试图让我输入 PIN,而 Bluez 无法做到这一点)。然后我需要将类更改为 Keyboard(通过运行我的 bithdd 程序)并强制 iPad 重新连接,以便它从 SDP 获取协议描述符并尝试连接到 L2CAP 端口 17 和 19。

问题 3:

是的,差不多就是这样——我认为你不会错过任何重要的事情。

祝你今天过得愉快!

于 2012-01-02T08:34:28.163 回答