撸蓝牙5 – 操蛋的HID

/ 0评 / 0

蓝牙协议真的非常操蛋,好难学啊.
今天直接跳到hids_init来看.终于看到懂得了,这不是USB的描述符吗?

大致看了看,果然是啊.只不过一个有线一个无线,也是有很多设备种类,比如关于HID初始化就有这些东西.

typedef struct
{
    ble_hids_evt_handler_t        evt_handler;                                  /**< Event handler to be called for handling events in the HID Service. */
    ble_srv_error_handler_t       error_handler;                                /**< Function to be called in case of an error. */
    bool                          is_kb;                                        /**< TRUE if device is operating as a keyboard, FALSE if it is not. */
    bool                          is_mouse;                                     /**< TRUE if device is operating as a mouse, FALSE if it is not. */
    uint8_t                       inp_rep_count;                                /**< Number of Input Report characteristics. */
    ble_hids_inp_rep_init_t *     p_inp_rep_array;                              /**< Information about the Input Report characteristics. */
    uint8_t                       outp_rep_count;                               /**< Number of Output Report characteristics. */
    ble_hids_outp_rep_init_t *    p_outp_rep_array;                             /**< Information about the Output Report characteristics. */
    uint8_t                       feature_rep_count;                            /**< Number of Feature Report characteristics. */
    ble_hids_feature_rep_init_t * p_feature_rep_array;                          /**< Information about the Feature Report characteristics. */
    ble_hids_rep_map_init_t       rep_map;                                      /**< Information nedeed for initialization of the Report Map characteristic. */
    ble_hids_hid_information_t    hid_information;                              /**< Value of the HID Information characteristic. */
    uint8_t                       included_services_count;                      /**< Number of services to include in HID service. */
    uint16_t *                    p_included_services_array;                    /**< Array of services to include in HID service. */
    ble_srv_security_mode_t       security_mode_protocol;                       /**< Security settings for HID service protocol attribute */
    ble_srv_security_mode_t       security_mode_ctrl_point;                     /**< Security settings for HID service Control Point attribute */
    ble_srv_cccd_security_mode_t  security_mode_boot_mouse_inp_rep;             /**< Security settings for HID service Mouse input report attribute */
    ble_srv_cccd_security_mode_t  security_mode_boot_kb_inp_rep;                /**< Security settings for HID service Keyboard input report attribute */
    ble_srv_security_mode_t       security_mode_boot_kb_outp_rep;               /**< Security settings for HID service Keyboard output report attribute */
} ble_hids_init_t;

而且很好理解,is_kb就是是不是键盘,我们是鼠标所以是is_mouse = true,然后rep_map其实就是描述符的内容,把描述符赋值过去,然后执行初始化,整个过程就完成了,这估计是最简单一部了,如果有USB开发经验,看描述符不是什么难度的问题.

就是把这个hids_init_obj全部赋值好了,就初始化,看情况m_hids函数的输出.
发送函数确实也是很像USB的.

因为这里只发了INPUT_REP_MOVEMENT_INDEX,所以只有方向.跟USB不同的是,数值是0x0FFF最大,USB是0xFF最大.那按键去哪里了呢?其实也是有初始化的.

其中INPUT_REP_MOVEMENT_LEN是3,也就是刚好buffer也是3,但是INPUT_REP_BUTTONS_LEN也是3,也就是按键也要发3个字节的,为什么是3个字节,我有点懵逼.只能看看描述符.

    static uint8_t rep_map_data[] =
    {
        0x05, 0x01, // Usage Page (Generic Desktop)
        0x09, 0x02, // Usage (Mouse)
        0xA1, 0x01, // Collection (Application)
        // Report ID 1: Mouse buttons + scroll/pan
        0x85, 0x01,       // Report Id 1
        0x09, 0x01,       // Usage (Pointer)
        0xA1, 0x00,       // Collection (Physical)
        0x95, 0x05,       // Report Count (3)
        0x75, 0x01,       // Report Size (1)
        0x05, 0x09,       // Usage Page (Buttons)
        0x19, 0x01,       // Usage Minimum (01)
        0x29, 0x05,       // Usage Maximum (05)
        0x15, 0x00,       // Logical Minimum (0)
        0x25, 0x01,       // Logical Maximum (1)
        0x81, 0x02,       // Input (Data, Variable, Absolute)
        0x95, 0x01,       // Report Count (1)
        0x75, 0x03,       // Report Size (3)
        0x81, 0x01,       // Input (Constant) for padding
        0x75, 0x08,       // Report Size (8)
        0x95, 0x01,       // Report Count (1)
        0x05, 0x01,       // Usage Page (Generic Desktop)
        0x09, 0x38,       // Usage (Wheel)
        0x15, 0x81,       // Logical Minimum (-127)
        0x25, 0x7F,       // Logical Maximum (127)
        0x81, 0x06,       // Input (Data, Variable, Relative)
        0x05, 0x0C,       // Usage Page (Consumer)
        0x0A, 0x38, 0x02, // Usage (AC Pan)
        0x95, 0x01,       // Report Count (1)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0xC0,             // End Collection (Physical)
        // Report ID 2: Mouse motion
        0x85, 0x02,       // Report Id 2
        0x09, 0x01,       // Usage (Pointer)
        0xA1, 0x00,       // Collection (Physical)
        0x75, 0x0C,       // Report Size (12)
        0x95, 0x02,       // Report Count (2)
        0x05, 0x01,       // Usage Page (Generic Desktop)
        0x09, 0x30,       // Usage (X)
        0x09, 0x31,       // Usage (Y)
        0x16, 0x01, 0xF8, // Logical maximum (2047)
        0x26, 0xFF, 0x07, // Logical minimum (-2047)
        0x81, 0x06,       // Input (Data, Variable, Relative)
        0xC0,             // End Collection (Physical)
        0xC0,             // End Collection (Application)
        // Report ID 3: Advanced buttons
        0x05, 0x0C,       // Usage Page (Consumer)
        0x09, 0x01,       // Usage (Consumer Control)
        0xA1, 0x01,       // Collection (Application)
        0x85, 0x03,       // Report Id (3)
        0x15, 0x00,       // Logical minimum (0)
        0x25, 0x01,       // Logical maximum (1)
        0x75, 0x01,       // Report Size (1)
        0x95, 0x01,       // Report Count (1)
        0x09, 0xCD,       // Usage (Play/Pause)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x09, 0xB5,       // Usage (Scan Next Track)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x09, 0xB6,       // Usage (Scan Previous Track)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x09, 0xEA,       // Usage (Volume Down)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x09, 0xE9,       // Usage (Volume Up)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x0A, 0x25, 0x02, // Usage (AC Forward)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0x0A, 0x24, 0x02, // Usage (AC Back)
        0x81, 0x06,       // Input (Data,Value,Relative,Bit Field)
        0xC0              // End Collection
    };

鼠标坐标的报告里面,给了X,Y是正负2047啊,难怪要0xFFF,然后按键也给了3个,最主要看Usage,这鼠标有点高级,有Pan(不知道什么),Wheel(滚轮),还有5个按键.没法想象这鼠标样子了.如果结合第三个特性,还有很多多媒体功能,表示震惊了.
这估计是我最看得懂的一节了,先歇会吧.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注