Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/holtmann/bluetooth-2.6
  • Loading branch information
David S. Miller committed Jul 19, 2008
2 parents 7abbcd6 + b1235d7 commit 407d819
Show file tree
Hide file tree
Showing 18 changed files with 1,112 additions and 271 deletions.
1 change: 1 addition & 0 deletions fs/compat_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,7 @@ COMPATIBLE_IOCTL(HCIGETDEVLIST)
COMPATIBLE_IOCTL(HCIGETDEVINFO)
COMPATIBLE_IOCTL(HCIGETCONNLIST)
COMPATIBLE_IOCTL(HCIGETCONNINFO)
COMPATIBLE_IOCTL(HCIGETAUTHINFO)
COMPATIBLE_IOCTL(HCISETRAW)
COMPATIBLE_IOCTL(HCISETSCAN)
COMPATIBLE_IOCTL(HCISETAUTH)
Expand Down
1 change: 1 addition & 0 deletions include/net/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ 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_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);

void bt_accept_enqueue(struct sock *parent, struct sock *sk);
Expand Down
68 changes: 64 additions & 4 deletions include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ enum {
HCI_INQUIRY,

HCI_RAW,

HCI_SECMGR
};

/* HCI ioctl defines */
Expand All @@ -86,6 +84,7 @@ enum {
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCIGETAUTHINFO _IOR('H', 215, int)

#define HCISETRAW _IOW('H', 220, int)
#define HCISETSCAN _IOW('H', 221, int)
Expand All @@ -97,8 +96,6 @@ enum {
#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 */
Expand Down Expand Up @@ -137,6 +134,8 @@ enum {
#define ESCO_EV4 0x0010
#define ESCO_EV5 0x0020

#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)

/* ACL flags */
#define ACL_CONT 0x01
#define ACL_START 0x02
Expand Down Expand Up @@ -178,6 +177,8 @@ enum {

#define LMP_SNIFF_SUBR 0x02

#define LMP_SIMPLE_PAIR 0x08

/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
#define HCI_CM_HOLD 0x0001
Expand All @@ -199,6 +200,14 @@ enum {
#define HCI_LM_RELIABLE 0x0010
#define HCI_LM_SECURE 0x0020

/* Authentication types */
#define HCI_AT_NO_BONDING 0x00
#define HCI_AT_NO_BONDING_MITM 0x01
#define HCI_AT_DEDICATED_BONDING 0x02
#define HCI_AT_DEDICATED_BONDING_MITM 0x03
#define HCI_AT_GENERAL_BONDING 0x04
#define HCI_AT_GENERAL_BONDING_MITM 0x05

/* ----- HCI Commands ---- */
#define HCI_OP_INQUIRY 0x0401
struct hci_cp_inquiry {
Expand Down Expand Up @@ -402,6 +411,17 @@ struct hci_rp_write_link_policy {
__le16 handle;
} __attribute__ ((packed));

#define HCI_OP_READ_DEF_LINK_POLICY 0x080e
struct hci_rp_read_def_link_policy {
__u8 status;
__le16 policy;
} __attribute__ ((packed));

#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f
struct hci_cp_write_def_link_policy {
__le16 policy;
} __attribute__ ((packed));

#define HCI_OP_SNIFF_SUBRATE 0x0811
struct hci_cp_sniff_subrate {
__le16 handle;
Expand Down Expand Up @@ -501,6 +521,17 @@ struct hci_cp_host_buffer_size {
__le16 sco_max_pkt;
} __attribute__ ((packed));

#define HCI_OP_READ_SSP_MODE 0x0c55
struct hci_rp_read_ssp_mode {
__u8 status;
__u8 mode;
} __attribute__ ((packed));

#define HCI_OP_WRITE_SSP_MODE 0x0c56
struct hci_cp_write_ssp_mode {
__u8 mode;
} __attribute__ ((packed));

#define HCI_OP_READ_LOCAL_VERSION 0x1001
struct hci_rp_read_local_version {
__u8 status;
Expand Down Expand Up @@ -696,6 +727,13 @@ struct hci_ev_clock_offset {
__le16 clock_offset;
} __attribute__ ((packed));

#define HCI_EV_PKT_TYPE_CHANGE 0x1d
struct hci_ev_pkt_type_change {
__u8 status;
__le16 handle;
__le16 pkt_type;
} __attribute__ ((packed));

#define HCI_EV_PSCAN_REP_MODE 0x20
struct hci_ev_pscan_rep_mode {
bdaddr_t bdaddr;
Expand Down Expand Up @@ -774,6 +812,23 @@ struct extended_inquiry_info {
__u8 data[240];
} __attribute__ ((packed));

#define HCI_EV_IO_CAPA_REQUEST 0x31
struct hci_ev_io_capa_request {
bdaddr_t bdaddr;
} __attribute__ ((packed));

#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct hci_ev_simple_pair_complete {
__u8 status;
bdaddr_t bdaddr;
} __attribute__ ((packed));

#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
struct hci_ev_remote_host_features {
bdaddr_t bdaddr;
__u8 features[8];
} __attribute__ ((packed));

/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
struct hci_ev_stack_internal {
Expand Down Expand Up @@ -951,6 +1006,11 @@ struct hci_conn_info_req {
struct hci_conn_info conn_info[0];
};

struct hci_auth_info_req {
bdaddr_t bdaddr;
__u8 type;
};

struct hci_inquiry_req {
__u16 dev_id;
__u16 flags;
Expand Down
19 changes: 13 additions & 6 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct inquiry_data {
__u8 dev_class[3];
__le16 clock_offset;
__s8 rssi;
__u8 ssp_mode;
};

struct inquiry_entry {
Expand Down Expand Up @@ -75,6 +76,7 @@ struct hci_dev {
__u8 dev_class[3];
__u8 features[8];
__u8 commands[64];
__u8 ssp_mode;
__u8 hci_ver;
__u16 hci_rev;
__u16 manufacturer;
Expand Down Expand Up @@ -161,9 +163,12 @@ struct hci_conn {
__u8 attempt;
__u8 dev_class[3];
__u8 features[8];
__u8 ssp_mode;
__u16 interval;
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
__u8 auth_type;
__u8 power_save;
unsigned long pend;

Expand Down Expand Up @@ -344,7 +349,7 @@ static inline void hci_conn_put(struct hci_conn *conn)
if (conn->state == BT_CONNECTED) {
timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
if (!conn->out)
timeo *= 2;
timeo *= 5;
} else
timeo = msecs_to_jiffies(10);
} else
Expand Down Expand Up @@ -418,6 +423,7 @@ int hci_get_dev_list(void __user *arg);
int hci_get_dev_info(void __user *arg);
int hci_get_conn_list(void __user *arg);
int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg);

void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
Expand Down Expand Up @@ -459,6 +465,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)

/* ----- HCI protocols ----- */
struct hci_proto {
Expand All @@ -474,7 +481,7 @@ struct hci_proto {
int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
int (*auth_cfm) (struct hci_conn *conn, __u8 status);
int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
};

static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
Expand Down Expand Up @@ -532,17 +539,17 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
hp->auth_cfm(conn, status);
}

static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
{
register struct hci_proto *hp;

hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->encrypt_cfm)
hp->encrypt_cfm(conn, status);
hp->encrypt_cfm(conn, status, encrypt);

hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->encrypt_cfm)
hp->encrypt_cfm(conn, status);
hp->encrypt_cfm(conn, status, encrypt);
}

int hci_register_proto(struct hci_proto *hproto);
Expand Down Expand Up @@ -579,7 +586,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
{
struct list_head *p;

hci_proto_encrypt_cfm(conn, status);
hci_proto_encrypt_cfm(conn, status, encrypt);

read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
Expand Down
2 changes: 2 additions & 0 deletions include/net/bluetooth/rfcomm.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ struct rfcomm_dlc {
u8 addr;
u8 priority;
u8 v24_sig;
u8 remote_v24_sig;
u8 mscex;
u8 out;

u32 link_mode;

Expand Down
53 changes: 52 additions & 1 deletion net/bluetooth/af_bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <net/sock.h>
#include <asm/ioctls.h>

#if defined(CONFIG_KMOD)
#include <linux/kmod.h>
Expand All @@ -48,7 +49,7 @@
#define BT_DBG(D...)
#endif

#define VERSION "2.11"
#define VERSION "2.12"

/* Bluetooth sockets */
#define BT_MAX_PROTO 8
Expand Down Expand Up @@ -266,6 +267,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,

skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err == 0)
sock_recv_timestamp(msg, sk, skb);

skb_free_datagram(sk, skb);

Expand Down Expand Up @@ -329,6 +332,54 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
}
EXPORT_SYMBOL(bt_sock_poll);

int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
long amount;
int err;

BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);

switch (cmd) {
case TIOCOUTQ:
if (sk->sk_state == BT_LISTEN)
return -EINVAL;

amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
err = put_user(amount, (int __user *) arg);
break;

case TIOCINQ:
if (sk->sk_state == BT_LISTEN)
return -EINVAL;

lock_sock(sk);
skb = skb_peek(&sk->sk_receive_queue);
amount = skb ? skb->len : 0;
release_sock(sk);
err = put_user(amount, (int __user *) arg);
break;

case SIOCGSTAMP:
err = sock_get_timestamp(sk, (struct timeval __user *) arg);
break;

case SIOCGSTAMPNS:
err = sock_get_timestampns(sk, (struct timespec __user *) arg);
break;

default:
err = -ENOIOCTLCMD;
break;
}

return err;
}
EXPORT_SYMBOL(bt_sock_ioctl);

int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
{
DECLARE_WAITQUEUE(wait, current);
Expand Down
5 changes: 5 additions & 0 deletions net/bluetooth/bnep/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,11 @@ static int bnep_session(void *arg)
/* Delete network device */
unregister_netdev(dev);

/* Wakeup user-space polling for socket errors */
s->sock->sk->sk_err = EUNATCH;

wake_up_interruptible(s->sock->sk->sk_sleep);

/* Release the socket */
fput(s->sock->file);

Expand Down
Loading

0 comments on commit 407d819

Please sign in to comment.