1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun HIDP implementation for Linux Bluetooth stack (BlueZ). 3*4882a593Smuzhiyun Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org> 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun This program is free software; you can redistribute it and/or modify 6*4882a593Smuzhiyun it under the terms of the GNU General Public License version 2 as 7*4882a593Smuzhiyun published by the Free Software Foundation; 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 12*4882a593Smuzhiyun IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 13*4882a593Smuzhiyun CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 14*4882a593Smuzhiyun WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15*4882a593Smuzhiyun ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16*4882a593Smuzhiyun OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 19*4882a593Smuzhiyun COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 20*4882a593Smuzhiyun SOFTWARE IS DISCLAIMED. 21*4882a593Smuzhiyun */ 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #ifndef __HIDP_H 24*4882a593Smuzhiyun #define __HIDP_H 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #include <linux/types.h> 27*4882a593Smuzhiyun #include <linux/hid.h> 28*4882a593Smuzhiyun #include <linux/kref.h> 29*4882a593Smuzhiyun #include <net/bluetooth/bluetooth.h> 30*4882a593Smuzhiyun #include <net/bluetooth/l2cap.h> 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* HIDP header masks */ 33*4882a593Smuzhiyun #define HIDP_HEADER_TRANS_MASK 0xf0 34*4882a593Smuzhiyun #define HIDP_HEADER_PARAM_MASK 0x0f 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun /* HIDP transaction types */ 37*4882a593Smuzhiyun #define HIDP_TRANS_HANDSHAKE 0x00 38*4882a593Smuzhiyun #define HIDP_TRANS_HID_CONTROL 0x10 39*4882a593Smuzhiyun #define HIDP_TRANS_GET_REPORT 0x40 40*4882a593Smuzhiyun #define HIDP_TRANS_SET_REPORT 0x50 41*4882a593Smuzhiyun #define HIDP_TRANS_GET_PROTOCOL 0x60 42*4882a593Smuzhiyun #define HIDP_TRANS_SET_PROTOCOL 0x70 43*4882a593Smuzhiyun #define HIDP_TRANS_GET_IDLE 0x80 44*4882a593Smuzhiyun #define HIDP_TRANS_SET_IDLE 0x90 45*4882a593Smuzhiyun #define HIDP_TRANS_DATA 0xa0 46*4882a593Smuzhiyun #define HIDP_TRANS_DATC 0xb0 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun /* HIDP handshake results */ 49*4882a593Smuzhiyun #define HIDP_HSHK_SUCCESSFUL 0x00 50*4882a593Smuzhiyun #define HIDP_HSHK_NOT_READY 0x01 51*4882a593Smuzhiyun #define HIDP_HSHK_ERR_INVALID_REPORT_ID 0x02 52*4882a593Smuzhiyun #define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST 0x03 53*4882a593Smuzhiyun #define HIDP_HSHK_ERR_INVALID_PARAMETER 0x04 54*4882a593Smuzhiyun #define HIDP_HSHK_ERR_UNKNOWN 0x0e 55*4882a593Smuzhiyun #define HIDP_HSHK_ERR_FATAL 0x0f 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun /* HIDP control operation parameters */ 58*4882a593Smuzhiyun #define HIDP_CTRL_NOP 0x00 59*4882a593Smuzhiyun #define HIDP_CTRL_HARD_RESET 0x01 60*4882a593Smuzhiyun #define HIDP_CTRL_SOFT_RESET 0x02 61*4882a593Smuzhiyun #define HIDP_CTRL_SUSPEND 0x03 62*4882a593Smuzhiyun #define HIDP_CTRL_EXIT_SUSPEND 0x04 63*4882a593Smuzhiyun #define HIDP_CTRL_VIRTUAL_CABLE_UNPLUG 0x05 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* HIDP data transaction headers */ 66*4882a593Smuzhiyun #define HIDP_DATA_RTYPE_MASK 0x03 67*4882a593Smuzhiyun #define HIDP_DATA_RSRVD_MASK 0x0c 68*4882a593Smuzhiyun #define HIDP_DATA_RTYPE_OTHER 0x00 69*4882a593Smuzhiyun #define HIDP_DATA_RTYPE_INPUT 0x01 70*4882a593Smuzhiyun #define HIDP_DATA_RTYPE_OUPUT 0x02 71*4882a593Smuzhiyun #define HIDP_DATA_RTYPE_FEATURE 0x03 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* HIDP protocol header parameters */ 74*4882a593Smuzhiyun #define HIDP_PROTO_BOOT 0x00 75*4882a593Smuzhiyun #define HIDP_PROTO_REPORT 0x01 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* HIDP ioctl defines */ 78*4882a593Smuzhiyun #define HIDPCONNADD _IOW('H', 200, int) 79*4882a593Smuzhiyun #define HIDPCONNDEL _IOW('H', 201, int) 80*4882a593Smuzhiyun #define HIDPGETCONNLIST _IOR('H', 210, int) 81*4882a593Smuzhiyun #define HIDPGETCONNINFO _IOR('H', 211, int) 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun #define HIDP_VIRTUAL_CABLE_UNPLUG 0 84*4882a593Smuzhiyun #define HIDP_BOOT_PROTOCOL_MODE 1 85*4882a593Smuzhiyun #define HIDP_BLUETOOTH_VENDOR_ID 9 86*4882a593Smuzhiyun #define HIDP_WAITING_FOR_RETURN 10 87*4882a593Smuzhiyun #define HIDP_WAITING_FOR_SEND_ACK 11 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun struct hidp_connadd_req { 90*4882a593Smuzhiyun int ctrl_sock; /* Connected control socket */ 91*4882a593Smuzhiyun int intr_sock; /* Connected interrupt socket */ 92*4882a593Smuzhiyun __u16 parser; 93*4882a593Smuzhiyun __u16 rd_size; 94*4882a593Smuzhiyun __u8 __user *rd_data; 95*4882a593Smuzhiyun __u8 country; 96*4882a593Smuzhiyun __u8 subclass; 97*4882a593Smuzhiyun __u16 vendor; 98*4882a593Smuzhiyun __u16 product; 99*4882a593Smuzhiyun __u16 version; 100*4882a593Smuzhiyun __u32 flags; 101*4882a593Smuzhiyun __u32 idle_to; 102*4882a593Smuzhiyun char name[128]; 103*4882a593Smuzhiyun }; 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun struct hidp_conndel_req { 106*4882a593Smuzhiyun bdaddr_t bdaddr; 107*4882a593Smuzhiyun __u32 flags; 108*4882a593Smuzhiyun }; 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun struct hidp_conninfo { 111*4882a593Smuzhiyun bdaddr_t bdaddr; 112*4882a593Smuzhiyun __u32 flags; 113*4882a593Smuzhiyun __u16 state; 114*4882a593Smuzhiyun __u16 vendor; 115*4882a593Smuzhiyun __u16 product; 116*4882a593Smuzhiyun __u16 version; 117*4882a593Smuzhiyun char name[128]; 118*4882a593Smuzhiyun }; 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun struct hidp_connlist_req { 121*4882a593Smuzhiyun __u32 cnum; 122*4882a593Smuzhiyun struct hidp_conninfo __user *ci; 123*4882a593Smuzhiyun }; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun int hidp_connection_add(const struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 126*4882a593Smuzhiyun int hidp_connection_del(struct hidp_conndel_req *req); 127*4882a593Smuzhiyun int hidp_get_connlist(struct hidp_connlist_req *req); 128*4882a593Smuzhiyun int hidp_get_conninfo(struct hidp_conninfo *ci); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun enum hidp_session_state { 131*4882a593Smuzhiyun HIDP_SESSION_IDLING, 132*4882a593Smuzhiyun HIDP_SESSION_PREPARING, 133*4882a593Smuzhiyun HIDP_SESSION_RUNNING, 134*4882a593Smuzhiyun }; 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* HIDP session defines */ 137*4882a593Smuzhiyun struct hidp_session { 138*4882a593Smuzhiyun struct list_head list; 139*4882a593Smuzhiyun struct kref ref; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun /* runtime management */ 142*4882a593Smuzhiyun atomic_t state; 143*4882a593Smuzhiyun wait_queue_head_t state_queue; 144*4882a593Smuzhiyun atomic_t terminate; 145*4882a593Smuzhiyun struct task_struct *task; 146*4882a593Smuzhiyun unsigned long flags; 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* connection management */ 149*4882a593Smuzhiyun bdaddr_t bdaddr; 150*4882a593Smuzhiyun struct l2cap_conn *conn; 151*4882a593Smuzhiyun struct l2cap_user user; 152*4882a593Smuzhiyun struct socket *ctrl_sock; 153*4882a593Smuzhiyun struct socket *intr_sock; 154*4882a593Smuzhiyun struct sk_buff_head ctrl_transmit; 155*4882a593Smuzhiyun struct sk_buff_head intr_transmit; 156*4882a593Smuzhiyun uint ctrl_mtu; 157*4882a593Smuzhiyun uint intr_mtu; 158*4882a593Smuzhiyun unsigned long idle_to; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun /* device management */ 161*4882a593Smuzhiyun struct work_struct dev_init; 162*4882a593Smuzhiyun struct input_dev *input; 163*4882a593Smuzhiyun struct hid_device *hid; 164*4882a593Smuzhiyun struct timer_list timer; 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun /* Report descriptor */ 167*4882a593Smuzhiyun __u8 *rd_data; 168*4882a593Smuzhiyun uint rd_size; 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun /* session data */ 171*4882a593Smuzhiyun unsigned char keys[8]; 172*4882a593Smuzhiyun unsigned char leds; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun /* Used in hidp_get_raw_report() */ 175*4882a593Smuzhiyun int waiting_report_type; /* HIDP_DATA_RTYPE_* */ 176*4882a593Smuzhiyun int waiting_report_number; /* -1 for not numbered */ 177*4882a593Smuzhiyun struct mutex report_mutex; 178*4882a593Smuzhiyun struct sk_buff *report_return; 179*4882a593Smuzhiyun wait_queue_head_t report_queue; 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /* Used in hidp_output_raw_report() */ 182*4882a593Smuzhiyun int output_report_success; /* boolean */ 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /* temporary input buffer */ 185*4882a593Smuzhiyun u8 input_buf[HID_MAX_BUFFER_SIZE]; 186*4882a593Smuzhiyun }; 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun /* HIDP init defines */ 189*4882a593Smuzhiyun int __init hidp_init_sockets(void); 190*4882a593Smuzhiyun void __exit hidp_cleanup_sockets(void); 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun #endif /* __HIDP_H */ 193