diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/net/bluetooth |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 181 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 755 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 626 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 238 | ||||
-rw-r--r-- | include/net/bluetooth/rfcomm.h | 353 | ||||
-rw-r--r-- | include/net/bluetooth/sco.h | 79 |
6 files changed, 2232 insertions, 0 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h new file mode 100644 index 00000000000..42a84c53678 --- /dev/null +++ b/include/net/bluetooth/bluetooth.h @@ -0,0 +1,181 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +#ifndef __BLUETOOTH_H +#define __BLUETOOTH_H + +#include <asm/types.h> +#include <asm/byteorder.h> +#include <linux/list.h> +#include <linux/poll.h> +#include <net/sock.h> + +#ifndef AF_BLUETOOTH +#define AF_BLUETOOTH 31 +#define PF_BLUETOOTH AF_BLUETOOTH +#endif + +/* Reserv for core and drivers use */ +#define BT_SKB_RESERVE 8 + +#define BTPROTO_L2CAP 0 +#define BTPROTO_HCI 1 +#define BTPROTO_SCO 2 +#define BTPROTO_RFCOMM 3 +#define BTPROTO_BNEP 4 +#define BTPROTO_CMTP 5 +#define BTPROTO_HIDP 6 +#define BTPROTO_AVDTP 7 + +#define SOL_HCI 0 +#define SOL_L2CAP 6 +#define SOL_SCO 17 +#define SOL_RFCOMM 18 + +#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) +#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) +#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) + +#ifdef HCI_DATA_DUMP +#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len) +#else +#define BT_DMP(D...) +#endif + +extern struct proc_dir_entry *proc_bt; + +/* Connection and socket states */ +enum { + BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ + BT_OPEN, + BT_BOUND, + BT_LISTEN, + BT_CONNECT, + BT_CONNECT2, + BT_CONFIG, + BT_DISCONN, + BT_CLOSED +}; + +/* Endianness conversions */ +#define htobs(a) __cpu_to_le16(a) +#define htobl(a) __cpu_to_le32(a) +#define btohs(a) __le16_to_cpu(a) +#define btohl(a) __le32_to_cpu(a) + +/* BD Address */ +typedef struct { + __u8 b[6]; +} __attribute__((packed)) bdaddr_t; + +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) + +/* Copy, swap, convert BD Address */ +static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) +{ + return memcmp(ba1, ba2, sizeof(bdaddr_t)); +} +static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) +{ + memcpy(dst, src, sizeof(bdaddr_t)); +} + +void baswap(bdaddr_t *dst, bdaddr_t *src); +char *batostr(bdaddr_t *ba); +bdaddr_t *strtoba(char *str); + +/* Common socket structures and functions */ + +#define bt_sk(__sk) ((struct bt_sock *) __sk) + +struct bt_sock { + struct sock sk; + bdaddr_t src; + bdaddr_t dst; + struct list_head accept_q; + struct sock *parent; +}; + +struct bt_sock_list { + struct hlist_head head; + rwlock_t lock; +}; + +int bt_sock_register(int proto, struct net_proto_family *ops); +int bt_sock_unregister(int proto); +void bt_sock_link(struct bt_sock_list *l, struct sock *s); +void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); +int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); +uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); +int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); + +void bt_accept_enqueue(struct sock *parent, struct sock *sk); +void bt_accept_unlink(struct sock *sk); +struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); + +/* Skb helpers */ +struct bt_skb_cb { + int incoming; +}; +#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) + +static inline struct sk_buff *bt_skb_alloc(unsigned int len, int how) +{ + struct sk_buff *skb; + + if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { + skb_reserve(skb, BT_SKB_RESERVE); + bt_cb(skb)->incoming = 0; + } + return skb; +} + +static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len, + int nb, int *err) +{ + struct sk_buff *skb; + + if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { + skb_reserve(skb, BT_SKB_RESERVE); + bt_cb(skb)->incoming = 0; + } + + return skb; +} + +static inline int skb_frags_no(struct sk_buff *skb) +{ + register struct sk_buff *frag = skb_shinfo(skb)->frag_list; + register int n = 1; + + for (; frag; frag=frag->next, n++); + return n; +} + +void bt_dump(char *pref, __u8 *buf, int count); + +int bt_err(__u16 code); + +#endif /* __BLUETOOTH_H */ diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h new file mode 100644 index 00000000000..6f0706f4af6 --- /dev/null +++ b/include/net/bluetooth/hci.h @@ -0,0 +1,755 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +#ifndef __HCI_H +#define __HCI_H + +#define HCI_MAX_ACL_SIZE 1024 +#define HCI_MAX_SCO_SIZE 255 +#define HCI_MAX_EVENT_SIZE 260 +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) + +/* HCI dev events */ +#define HCI_DEV_REG 1 +#define HCI_DEV_UNREG 2 +#define HCI_DEV_UP 3 +#define HCI_DEV_DOWN 4 +#define HCI_DEV_SUSPEND 5 +#define HCI_DEV_RESUME 6 + +/* HCI notify events */ +#define HCI_NOTIFY_CONN_ADD 1 +#define HCI_NOTIFY_CONN_DEL 2 +#define HCI_NOTIFY_VOICE_SETTING 3 + +/* HCI device types */ +#define HCI_VHCI 0 +#define HCI_USB 1 +#define HCI_PCCARD 2 +#define HCI_UART 3 +#define HCI_RS232 4 +#define HCI_PCI 5 + +/* HCI device quirks */ +enum { + HCI_QUIRK_RESET_ON_INIT, + HCI_QUIRK_RAW_DEVICE +}; + +/* HCI device flags */ +enum { + HCI_UP, + HCI_INIT, + HCI_RUNNING, + + HCI_PSCAN, + HCI_ISCAN, + HCI_AUTH, + HCI_ENCRYPT, + HCI_INQUIRY, + + HCI_RAW, + + HCI_SECMGR +}; + +/* HCI ioctl defines */ +#define HCIDEVUP _IOW('H', 201, int) +#define HCIDEVDOWN _IOW('H', 202, int) +#define HCIDEVRESET _IOW('H', 203, int) +#define HCIDEVRESTAT _IOW('H', 204, int) + +#define HCIGETDEVLIST _IOR('H', 210, int) +#define HCIGETDEVINFO _IOR('H', 211, int) +#define HCIGETCONNLIST _IOR('H', 212, int) +#define HCIGETCONNINFO _IOR('H', 213, int) + +#define HCISETRAW _IOW('H', 220, int) +#define HCISETSCAN _IOW('H', 221, int) +#define HCISETAUTH _IOW('H', 222, int) +#define HCISETENCRYPT _IOW('H', 223, int) +#define HCISETPTYPE _IOW('H', 224, int) +#define HCISETLINKPOL _IOW('H', 225, int) +#define HCISETLINKMODE _IOW('H', 226, int) +#define HCISETACLMTU _IOW('H', 227, int) +#define HCISETSCOMTU _IOW('H', 228, int) + +#define HCISETSECMGR _IOW('H', 230, int) + +#define HCIINQUIRY _IOR('H', 240, int) + +/* HCI timeouts */ +#define HCI_CONN_TIMEOUT (HZ * 40) +#define HCI_DISCONN_TIMEOUT (HZ * 2) +#define HCI_CONN_IDLE_TIMEOUT (HZ * 60) + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +/* HCI Packet types */ +#define HCI_DM1 0x0008 +#define HCI_DM3 0x0400 +#define HCI_DM5 0x4000 +#define HCI_DH1 0x0010 +#define HCI_DH3 0x0800 +#define HCI_DH5 0x8000 + +#define HCI_HV1 0x0020 +#define HCI_HV2 0x0040 +#define HCI_HV3 0x0080 + +#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) +#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) + +/* ACL flags */ +#define ACL_CONT 0x01 +#define ACL_START 0x02 +#define ACL_ACTIVE_BCAST 0x04 +#define ACL_PICO_BCAST 0x08 + +/* Baseband links */ +#define SCO_LINK 0x00 +#define ACL_LINK 0x01 + +/* LMP features */ +#define LMP_3SLOT 0x01 +#define LMP_5SLOT 0x02 +#define LMP_ENCRYPT 0x04 +#define LMP_SOFFSET 0x08 +#define LMP_TACCURACY 0x10 +#define LMP_RSWITCH 0x20 +#define LMP_HOLD 0x40 +#define LMP_SNIF 0x80 + +#define LMP_PARK 0x01 +#define LMP_RSSI 0x02 +#define LMP_QUALITY 0x04 +#define LMP_SCO 0x08 +#define LMP_HV2 0x10 +#define LMP_HV3 0x20 +#define LMP_ULAW 0x40 +#define LMP_ALAW 0x80 + +#define LMP_CVSD 0x01 +#define LMP_PSCHEME 0x02 +#define LMP_PCONTROL 0x04 + +/* Link policies */ +#define HCI_LP_RSWITCH 0x0001 +#define HCI_LP_HOLD 0x0002 +#define HCI_LP_SNIFF 0x0004 +#define HCI_LP_PARK 0x0008 + +/* Link mode */ +#define HCI_LM_ACCEPT 0x8000 +#define HCI_LM_MASTER 0x0001 +#define HCI_LM_AUTH 0x0002 +#define HCI_LM_ENCRYPT 0x0004 +#define HCI_LM_TRUSTED 0x0008 +#define HCI_LM_RELIABLE 0x0010 +#define HCI_LM_SECURE 0x0020 + +/* ----- HCI Commands ---- */ +/* OGF & OCF values */ + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +struct hci_rp_read_loc_version { + __u8 status; + __u8 hci_ver; + __u16 hci_rev; + __u8 lmp_ver; + __u16 manufacturer; + __u16 lmp_subver; +} __attribute__ ((packed)); + +#define OCF_READ_LOCAL_FEATURES 0x0003 +struct hci_rp_read_loc_features { + __u8 status; + __u8 features[8]; +} __attribute__ ((packed)); + +#define OCF_READ_BUFFER_SIZE 0x0005 +struct hci_rp_read_buffer_size { + __u8 status; + __u16 acl_mtu; + __u8 sco_mtu; + __u16 acl_max_pkt; + __u16 sco_max_pkt; +} __attribute__ ((packed)); + +#define OCF_READ_BD_ADDR 0x0009 +struct hci_rp_read_bd_addr { + __u8 status; + bdaddr_t bdaddr; +} __attribute__ ((packed)); + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 +#define OCF_RESET 0x0003 +#define OCF_READ_AUTH_ENABLE 0x001F +#define OCF_WRITE_AUTH_ENABLE 0x0020 + #define AUTH_DISABLED 0x00 + #define AUTH_ENABLED 0x01 + +#define OCF_READ_ENCRYPT_MODE 0x0021 +#define OCF_WRITE_ENCRYPT_MODE 0x0022 + #define ENCRYPT_DISABLED 0x00 + #define ENCRYPT_P2P 0x01 + #define ENCRYPT_BOTH 0x02 + +#define OCF_WRITE_CA_TIMEOUT 0x0016 +#define OCF_WRITE_PG_TIMEOUT 0x0018 + +#define OCF_WRITE_SCAN_ENABLE 0x001A + #define SCAN_DISABLED 0x00 + #define SCAN_INQUIRY 0x01 + #define SCAN_PAGE 0x02 + +#define OCF_SET_EVENT_FLT 0x0005 +struct hci_cp_set_event_flt { + __u8 flt_type; + __u8 cond_type; + __u8 condition[0]; +} __attribute__ ((packed)); + +/* Filter types */ +#define HCI_FLT_CLEAR_ALL 0x00 +#define HCI_FLT_INQ_RESULT 0x01 +#define HCI_FLT_CONN_SETUP 0x02 + +/* CONN_SETUP Condition types */ +#define HCI_CONN_SETUP_ALLOW_ALL 0x00 +#define HCI_CONN_SETUP_ALLOW_CLASS 0x01 +#define HCI_CONN_SETUP_ALLOW_BDADDR 0x02 + +/* CONN_SETUP Conditions */ +#define HCI_CONN_SETUP_AUTO_OFF 0x01 +#define HCI_CONN_SETUP_AUTO_ON 0x02 + +#define OCF_READ_CLASS_OF_DEV 0x0023 +struct hci_rp_read_dev_class { + __u8 status; + __u8 dev_class[3]; +} __attribute__ ((packed)); + +#define OCF_WRITE_CLASS_OF_DEV 0x0024 +struct hci_cp_write_dev_class { + __u8 dev_class[3]; +} __attribute__ ((packed)); + +#define OCF_READ_VOICE_SETTING 0x0025 +struct hci_rp_read_voice_setting { + __u8 status; + __u16 voice_setting; +} __attribute__ ((packed)); + +#define OCF_WRITE_VOICE_SETTING 0x0026 +struct hci_cp_write_voice_setting { + __u16 voice_setting; +} __attribute__ ((packed)); + +#define OCF_HOST_BUFFER_SIZE 0x0033 +struct hci_cp_host_buffer_size { + __u16 acl_mtu; + __u8 sco_mtu; + __u16 acl_max_pkt; + __u16 sco_max_pkt; +} __attribute__ ((packed)); + +/* Link Control */ +#define OGF_LINK_CTL 0x01 +#define OCF_CREATE_CONN 0x0005 +struct hci_cp_create_conn { + bdaddr_t bdaddr; + __u16 pkt_type; + __u8 pscan_rep_mode; + __u8 pscan_mode; + __u16 clock_offset; + __u8 role_switch; +} __attribute__ ((packed)); + +#define OCF_ACCEPT_CONN_REQ 0x0009 +struct hci_cp_accept_conn_req { + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)); + +#define OCF_REJECT_CONN_REQ 0x000a +struct hci_cp_reject_conn_req { + bdaddr_t bdaddr; + __u8 reason; +} __attribute__ ((packed)); + +#define OCF_DISCONNECT 0x0006 +struct hci_cp_disconnect { + __u16 handle; + __u8 reason; +} __attribute__ ((packed)); + +#define OCF_ADD_SCO 0x0007 +struct hci_cp_add_sco { + __u16 handle; + __u16 pkt_type; +} __attribute__ ((packed)); + +#define OCF_INQUIRY 0x0001 +struct hci_cp_inquiry { + __u8 lap[3]; + __u8 length; + __u8 num_rsp; +} __attribute__ ((packed)); + +#define OCF_INQUIRY_CANCEL 0x0002 + +#define OCF_LINK_KEY_REPLY 0x000B +struct hci_cp_link_key_reply { + bdaddr_t bdaddr; + __u8 link_key[16]; +} __attribute__ ((packed)); + +#define OCF_LINK_KEY_NEG_REPLY 0x000C +struct hci_cp_link_key_neg_reply { + bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define OCF_PIN_CODE_REPLY 0x000D +struct hci_cp_pin_code_reply { + bdaddr_t bdaddr; + __u8 pin_len; + __u8 pin_code[16]; +} __attribute__ ((packed)); + +#define OCF_PIN_CODE_NEG_REPLY 0x000E +struct hci_cp_pin_code_neg_reply { + bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define OCF_CHANGE_CONN_PTYPE 0x000F +struct hci_cp_change_conn_ptype { + __u16 handle; + __u16 pkt_type; +} __attribute__ ((packed)); + +#define OCF_AUTH_REQUESTED 0x0011 +struct hci_cp_auth_requested { + __u16 handle; +} __attribute__ ((packed)); + +#define OCF_SET_CONN_ENCRYPT 0x0013 +struct hci_cp_set_conn_encrypt { + __u16 handle; + __u8 encrypt; +} __attribute__ ((packed)); + +#define OCF_CHANGE_CONN_LINK_KEY 0x0015 +struct hci_cp_change_conn_link_key { + __u16 handle; +} __attribute__ ((packed)); + +#define OCF_READ_REMOTE_FEATURES 0x001B +struct hci_cp_read_rmt_features { + __u16 handle; +} __attribute__ ((packed)); + +#define OCF_READ_REMOTE_VERSION 0x001D +struct hci_cp_read_rmt_version { + __u16 handle; +} __attribute__ ((packed)); + +/* Link Policy */ +#define OGF_LINK_POLICY 0x02 +#define OCF_ROLE_DISCOVERY 0x0009 +struct hci_cp_role_discovery { + __u16 handle; +} __attribute__ ((packed)); +struct hci_rp_role_discovery { + __u8 status; + __u16 handle; + __u8 role; +} __attribute__ ((packed)); + +#define OCF_READ_LINK_POLICY 0x000C +struct hci_cp_read_link_policy { + __u16 handle; +} __attribute__ ((packed)); +struct hci_rp_read_link_policy { + __u8 status; + __u16 handle; + __u16 policy; +} __attribute__ ((packed)); + +#define OCF_SWITCH_ROLE 0x000B +struct hci_cp_switch_role { + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)); + +#define OCF_WRITE_LINK_POLICY 0x000D +struct hci_cp_write_link_policy { + __u16 handle; + __u16 policy; +} __attribute__ ((packed)); +struct hci_rp_write_link_policy { + __u8 status; + __u16 handle; +} __attribute__ ((packed)); + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +/* Testing commands */ +#define OGF_TESTING_CMD 0x3E + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3F + +/* ---- HCI Events ---- */ +#define HCI_EV_INQUIRY_COMPLETE 0x01 + +#define HCI_EV_INQUIRY_RESULT 0x02 +struct inquiry_info { + bdaddr_t bdaddr; + __u8 pscan_rep_mode; + __u8 pscan_period_mode; + __u8 pscan_mode; + __u8 dev_class[3]; + __u16 clock_offset; +} __attribute__ ((packed)); + +#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 +struct inquiry_info_with_rssi { + bdaddr_t bdaddr; + __u8 pscan_rep_mode; + __u8 pscan_period_mode; + __u8 dev_class[3]; + __u16 clock_offset; + __s8 rssi; +} __attribute__ ((packed)); + +#define HCI_EV_CONN_COMPLETE 0x03 +struct hci_ev_conn_complete { + __u8 status; + __u16 handle; + bdaddr_t bdaddr; + __u8 link_type; + __u8 encr_mode; +} __attribute__ ((packed)); + +#define HCI_EV_CONN_REQUEST 0x04 +struct hci_ev_conn_request { + bdaddr_t bdaddr; + __u8 dev_class[3]; + __u8 link_type; +} __attribute__ ((packed)); + +#define HCI_EV_DISCONN_COMPLETE 0x05 +struct hci_ev_disconn_complete { + __u8 status; + __u16 handle; + __u8 reason; +} __attribute__ ((packed)); + +#define HCI_EV_AUTH_COMPLETE 0x06 +struct hci_ev_auth_complete { + __u8 status; + __u16 handle; +} __attribute__ ((packed)); + +#define HCI_EV_ENCRYPT_CHANGE 0x08 +struct hci_ev_encrypt_change { + __u8 status; + __u16 handle; + __u8 encrypt; +} __attribute__ ((packed)); + +#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 +struct hci_ev_change_conn_link_key_complete { + __u8 status; + __u16 handle; +} __attribute__ ((packed)); + +#define HCI_EV_QOS_SETUP_COMPLETE 0x0D +struct hci_qos { + __u8 service_type; + __u32 token_rate; + __u32 peak_bandwidth; + __u32 latency; + __u32 delay_variation; +} __attribute__ ((packed)); +struct hci_ev_qos_setup_complete { + __u8 status; + __u16 handle; + struct hci_qos qos; +} __attribute__ ((packed)); + +#define HCI_EV_CMD_COMPLETE 0x0E +struct hci_ev_cmd_complete { + __u8 ncmd; + __u16 opcode; +} __attribute__ ((packed)); + +#define HCI_EV_CMD_STATUS 0x0F +struct hci_ev_cmd_status { + __u8 status; + __u8 ncmd; + __u16 opcode; +} __attribute__ ((packed)); + +#define HCI_EV_NUM_COMP_PKTS 0x13 +struct hci_ev_num_comp_pkts { + __u8 num_hndl; + /* variable length part */ +} __attribute__ ((packed)); + +#define HCI_EV_ROLE_CHANGE 0x12 +struct hci_ev_role_change { + __u8 status; + bdaddr_t bdaddr; + __u8 role; +} __attribute__ ((packed)); + +#define HCI_EV_MODE_CHANGE 0x14 +struct hci_ev_mode_change { + __u8 status; + __u16 handle; + __u8 mode; + __u16 interval; +} __attribute__ ((packed)); + +#define HCI_EV_PIN_CODE_REQ 0x16 +struct hci_ev_pin_code_req { + bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_EV_LINK_KEY_REQ 0x17 +struct hci_ev_link_key_req { + bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_EV_LINK_KEY_NOTIFY 0x18 +struct hci_ev_link_key_notify { + bdaddr_t bdaddr; + __u8 link_key[16]; + __u8 key_type; +} __attribute__ ((packed)); + +#define HCI_EV_RMT_FEATURES 0x0B +struct hci_ev_rmt_features { + __u8 status; + __u16 handle; + __u8 features[8]; +} __attribute__ ((packed)); + +#define HCI_EV_RMT_VERSION 0x0C +struct hci_ev_rmt_version { + __u8 status; + __u16 handle; + __u8 lmp_ver; + __u16 manufacturer; + __u16 lmp_subver; +} __attribute__ ((packed)); + +#define HCI_EV_CLOCK_OFFSET 0x01C +struct hci_ev_clock_offset { + __u8 status; + __u16 handle; + __u16 clock_offset; +} __attribute__ ((packed)); + +/* Internal events generated by Bluetooth stack */ +#define HCI_EV_STACK_INTERNAL 0xFD +struct hci_ev_stack_internal { + __u16 type; + __u8 data[0]; +} __attribute__ ((packed)); + +#define HCI_EV_SI_DEVICE 0x01 +struct hci_ev_si_device { + __u16 event; + __u16 dev_id; +} __attribute__ ((packed)); + +#define HCI_EV_SI_SECURITY 0x02 +struct hci_ev_si_security { + __u16 event; + __u16 proto; + __u16 subproto; + __u8 incoming; +} __attribute__ ((packed)); + +/* ---- HCI Packet structures ---- */ +#define HCI_COMMAND_HDR_SIZE 3 +#define HCI_EVENT_HDR_SIZE 2 +#define HCI_ACL_HDR_SIZE 4 +#define HCI_SCO_HDR_SIZE 3 + +struct hci_command_hdr { + __u16 opcode; /* OCF & OGF */ + __u8 plen; +} __attribute__ ((packed)); + +struct hci_event_hdr { + __u8 evt; + __u8 plen; +} __attribute__ ((packed)); + +struct hci_acl_hdr { + __u16 handle; /* Handle & Flags(PB, BC) */ + __u16 dlen; +} __attribute__ ((packed)); + +struct hci_sco_hdr { + __u16 handle; + __u8 dlen; +} __attribute__ ((packed)); + +/* Command opcode pack/unpack */ +#define hci_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10)) +#define hci_opcode_ogf(op) (op >> 10) +#define hci_opcode_ocf(op) (op & 0x03ff) + +/* ACL handle and flags pack/unpack */ +#define hci_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12)) +#define hci_handle(h) (h & 0x0fff) +#define hci_flags(h) (h >> 12) + +/* ---- HCI Sockets ---- */ + +/* Socket options */ +#define HCI_DATA_DIR 1 +#define HCI_FILTER 2 +#define HCI_TIME_STAMP 3 + +/* CMSG flags */ +#define HCI_CMSG_DIR 0x0001 +#define HCI_CMSG_TSTAMP 0x0002 + +struct sockaddr_hci { + sa_family_t hci_family; + unsigned short hci_dev; +}; +#define HCI_DEV_NONE 0xffff + +struct hci_filter { + unsigned long type_mask; + unsigned long event_mask[2]; + __u16 opcode; +}; + +struct hci_ufilter { + __u32 type_mask; + __u32 event_mask[2]; + __u16 opcode; +}; + +#define HCI_FLT_TYPE_BITS 31 +#define HCI_FLT_EVENT_BITS 63 +#define HCI_FLT_OGF_BITS 63 +#define HCI_FLT_OCF_BITS 127 + +/* ---- HCI Ioctl requests structures ---- */ +struct hci_dev_stats { + __u32 err_rx; + __u32 err_tx; + __u32 cmd_tx; + __u32 evt_rx; + __u32 acl_tx; + __u32 acl_rx; + __u32 sco_tx; + __u32 sco_rx; + __u32 byte_rx; + __u32 byte_tx; +}; + +struct hci_dev_info { + __u16 dev_id; + char name[8]; + + bdaddr_t bdaddr; + + __u32 flags; + __u8 type; + + __u8 features[8]; + + __u32 pkt_type; + __u32 link_policy; + __u32 link_mode; + + __u16 acl_mtu; + __u16 acl_pkts; + __u16 sco_mtu; + __u16 sco_pkts; + + struct hci_dev_stats stat; +}; + +struct hci_conn_info { + __u16 handle; + bdaddr_t bdaddr; + __u8 type; + __u8 out; + __u16 state; + __u32 link_mode; +}; + +struct hci_dev_req { + __u16 dev_id; + __u32 dev_opt; +}; + +struct hci_dev_list_req { + __u16 dev_num; + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ +}; + +struct hci_conn_list_req { + __u16 dev_id; + __u16 conn_num; + struct hci_conn_info conn_info[0]; +}; + +struct hci_conn_info_req { + bdaddr_t bdaddr; + __u8 type; + struct hci_conn_info conn_info[0]; +}; + +struct hci_inquiry_req { + __u16 dev_id; + __u16 flags; + __u8 lap[3]; + __u8 length; + __u8 num_rsp; +}; +#define IREQ_CACHE_FLUSH 0x0001 + +#endif /* __HCI_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h new file mode 100644 index 00000000000..6d63a47c731 --- /dev/null +++ b/include/net/bluetooth/hci_core.h @@ -0,0 +1,626 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +#ifndef __HCI_CORE_H +#define __HCI_CORE_H + +#include <linux/proc_fs.h> +#include <net/bluetooth/hci.h> + +/* HCI upper protocols */ +#define HCI_PROTO_L2CAP 0 +#define HCI_PROTO_SCO 1 + +#define HCI_INIT_TIMEOUT (HZ * 10) + +extern struct proc_dir_entry *proc_bt_hci; + +/* HCI Core structures */ + +struct inquiry_data { + bdaddr_t bdaddr; + __u8 pscan_rep_mode; + __u8 pscan_period_mode; + __u8 pscan_mode; + __u8 dev_class[3]; + __u16 clock_offset; + __s8 rssi; +}; + +struct inquiry_entry { + struct inquiry_entry *next; + __u32 timestamp; + struct inquiry_data data; +}; + +struct inquiry_cache { + spinlock_t lock; + __u32 timestamp; + struct inquiry_entry *list; +}; + +struct hci_conn_hash { + struct list_head list; + spinlock_t lock; + unsigned int acl_num; + unsigned int sco_num; +}; + +struct hci_dev { + struct list_head list; + spinlock_t lock; + atomic_t refcnt; + + char name[8]; + unsigned long flags; + __u16 id; + __u8 type; + bdaddr_t bdaddr; + __u8 features[8]; + __u16 voice_setting; + + __u16 pkt_type; + __u16 link_policy; + __u16 link_mode; + + unsigned long quirks; + + atomic_t cmd_cnt; + unsigned int acl_cnt; + unsigned int sco_cnt; + + unsigned int acl_mtu; + unsigned int sco_mtu; + unsigned int acl_pkts; + unsigned int sco_pkts; + + unsigned long cmd_last_tx; + unsigned long acl_last_tx; + unsigned long sco_last_tx; + + struct tasklet_struct cmd_task; + struct tasklet_struct rx_task; + struct tasklet_struct tx_task; + + struct sk_buff_head rx_q; + struct sk_buff_head raw_q; + struct sk_buff_head cmd_q; + + struct sk_buff *sent_cmd; + + struct semaphore req_lock; + wait_queue_head_t req_wait_q; + __u32 req_status; + __u32 req_result; + + struct inquiry_cache inq_cache; + struct hci_conn_hash conn_hash; + + struct hci_dev_stats stat; + + struct sk_buff_head driver_init; + + void *driver_data; + void *core_data; + + atomic_t promisc; + +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc; +#endif + + struct class_device class_dev; + + struct module *owner; + + int (*open)(struct hci_dev *hdev); + int (*close)(struct hci_dev *hdev); + int (*flush)(struct hci_dev *hdev); + int (*send)(struct sk_buff *skb); + void (*destruct)(struct hci_dev *hdev); + void (*notify)(struct hci_dev *hdev, unsigned int evt); + int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); +}; + +struct hci_conn { + struct list_head list; + + atomic_t refcnt; + spinlock_t lock; + + bdaddr_t dst; + __u16 handle; + __u16 state; + __u8 type; + __u8 out; + __u8 dev_class[3]; + __u32 link_mode; + unsigned long pend; + + unsigned int sent; + + struct sk_buff_head data_q; + + struct timer_list timer; + + struct hci_dev *hdev; + void *l2cap_data; + void *sco_data; + void *priv; + + struct hci_conn *link; +}; + +extern struct hci_proto *hci_proto[]; +extern struct list_head hci_dev_list; +extern struct list_head hci_cb_list; +extern rwlock_t hci_dev_list_lock; +extern rwlock_t hci_cb_list_lock; + +/* ----- Inquiry cache ----- */ +#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds +#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds + +#define inquiry_cache_lock(c) spin_lock(&c->lock) +#define inquiry_cache_unlock(c) spin_unlock(&c->lock) +#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) +#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) + +static inline void inquiry_cache_init(struct hci_dev *hdev) +{ + struct inquiry_cache *c = &hdev->inq_cache; + spin_lock_init(&c->lock); + c->list = NULL; +} + +static inline int inquiry_cache_empty(struct hci_dev *hdev) +{ + struct inquiry_cache *c = &hdev->inq_cache; + return (c->list == NULL); +} + +static inline long inquiry_cache_age(struct hci_dev *hdev) +{ + struct inquiry_cache *c = &hdev->inq_cache; + return jiffies - c->timestamp; +} + +static inline long inquiry_entry_age(struct inquiry_entry *e) +{ + return jiffies - e->timestamp; +} + +struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); +void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); + +/* ----- HCI Connections ----- */ +enum { + HCI_CONN_AUTH_PEND, + HCI_CONN_ENCRYPT_PEND, + HCI_CONN_RSWITCH_PEND +}; + +static inline void hci_conn_hash_init(struct hci_dev *hdev) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + INIT_LIST_HEAD(&h->list); + spin_lock_init(&h->lock); + h->acl_num = 0; + h->sco_num = 0; +} + +static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + list_add(&c->list, &h->list); + if (c->type == ACL_LINK) + h->acl_num++; + else + h->sco_num++; +} + +static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + list_del(&c->list); + if (c->type == ACL_LINK) + h->acl_num--; + else + h->sco_num--; +} + +static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, + __u16 handle) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + struct list_head *p; + struct hci_conn *c; + + list_for_each(p, &h->list) { |