Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

This commit is contained in:
John W. Linville
2012-05-16 15:38:11 -04:00
27 changed files with 1355 additions and 747 deletions
+24 -7
View File
@@ -163,6 +163,11 @@ typedef struct {
__u8 b[6];
} __packed bdaddr_t;
/* BD Address type */
#define BDADDR_BREDR 0x00
#define BDADDR_LE_PUBLIC 0x01
#define BDADDR_LE_RANDOM 0x02
#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
@@ -178,7 +183,6 @@ static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
void baswap(bdaddr_t *dst, bdaddr_t *src);
char *batostr(bdaddr_t *ba);
bdaddr_t *strtoba(char *str);
/* Common socket structures and functions */
@@ -190,7 +194,12 @@ struct bt_sock {
bdaddr_t dst;
struct list_head accept_q;
struct sock *parent;
u32 defer_setup;
unsigned long flags;
};
enum {
BT_SK_DEFER_SETUP,
BT_SK_SUSPEND,
};
struct bt_sock_list {
@@ -215,14 +224,24 @@ void bt_accept_unlink(struct sock *sk);
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct l2cap_ctrl {
unsigned int sframe : 1,
poll : 1,
final : 1,
fcs : 1,
sar : 2,
super : 2;
__u16 reqseq;
__u16 txseq;
__u8 retries;
};
struct bt_skb_cb {
__u8 pkt_type;
__u8 incoming;
__u16 expect;
__u16 tx_seq;
__u8 retries;
__u8 sar;
__u8 force_active;
struct l2cap_ctrl control;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
@@ -242,12 +261,10 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,
{
struct sk_buff *skb;
release_sock(sk);
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
lock_sock(sk);
if (!skb && *err)
return NULL;
+7 -1
View File
@@ -102,6 +102,7 @@ enum {
HCI_DISCOVERABLE,
HCI_LINK_SECURITY,
HCI_PENDING_CLASS,
HCI_PERIODIC_INQ,
};
/* HCI ioctl defines */
@@ -324,6 +325,8 @@ struct hci_cp_inquiry {
#define HCI_OP_INQUIRY_CANCEL 0x0402
#define HCI_OP_PERIODIC_INQ 0x0403
#define HCI_OP_EXIT_PERIODIC_INQ 0x0404
#define HCI_OP_CREATE_CONN 0x0405
@@ -717,6 +720,10 @@ struct hci_rp_read_local_oob_data {
} __packed;
#define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58
struct hci_rp_read_inq_rsp_tx_power {
__u8 status;
__s8 tx_power;
} __packed;
#define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66
struct hci_rp_read_flow_control_mode {
@@ -1431,6 +1438,5 @@ struct hci_inquiry_req {
#define IREQ_CACHE_FLUSH 0x0001
extern bool enable_hs;
extern bool enable_le;
#endif /* __HCI_H */
+36 -31
View File
@@ -155,9 +155,14 @@ struct hci_dev {
__u16 hci_rev;
__u8 lmp_ver;
__u16 manufacturer;
__le16 lmp_subver;
__u16 lmp_subver;
__u16 voice_setting;
__u8 io_capability;
__s8 inq_tx_power;
__u16 devid_source;
__u16 devid_vendor;
__u16 devid_product;
__u16 devid_version;
__u16 pkt_type;
__u16 esco_type;
@@ -250,9 +255,6 @@ struct hci_dev {
struct list_head remote_oob_data;
struct list_head adv_entries;
struct delayed_work adv_work;
struct hci_dev_stats stat;
struct sk_buff_head driver_init;
@@ -263,7 +265,6 @@ struct hci_dev {
struct dentry *debugfs;
struct device *parent;
struct device dev;
struct rfkill *rfkill;
@@ -571,7 +572,7 @@ int hci_chan_del(struct hci_chan *chan);
void hci_chan_list_flush(struct hci_conn *conn);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
__u8 sec_level, __u8 auth_type);
__u8 dst_type, __u8 sec_level, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
@@ -673,8 +674,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 ediv,
u8 rand[8]);
int new_key, u8 authenticated, u8 tk[16], u8 enc_size,
__le16 ediv, u8 rand[8]);
struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 addr_type);
int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
@@ -688,14 +689,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
u8 *randomizer);
int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
#define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */
int hci_adv_entries_clear(struct hci_dev *hdev);
struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_adv_entry(struct hci_dev *hdev,
struct hci_ev_le_advertising_info *ev);
void hci_del_off_timer(struct hci_dev *hdev);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
@@ -709,7 +702,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn);
#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
/* ----- LMP capabilities ----- */
#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH)
@@ -933,6 +926,23 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
return false;
}
static inline size_t eir_get_length(u8 *eir, size_t eir_len)
{
size_t parsed = 0;
while (parsed < eir_len) {
u8 field_len = eir[0];
if (field_len == 0)
return parsed;
parsed += field_len + 1;
eir += field_len + 1;
}
return eir_len;
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len)
{
@@ -961,17 +971,12 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb);
void hci_sock_dev_event(struct hci_dev *hdev, int event);
/* Management interface */
#define MGMT_ADDR_BREDR 0x00
#define MGMT_ADDR_LE_PUBLIC 0x01
#define MGMT_ADDR_LE_RANDOM 0x02
#define MGMT_ADDR_INVALID 0xff
#define DISCOV_TYPE_BREDR (BIT(MGMT_ADDR_BREDR))
#define DISCOV_TYPE_LE (BIT(MGMT_ADDR_LE_PUBLIC) | \
BIT(MGMT_ADDR_LE_RANDOM))
#define DISCOV_TYPE_INTERLEAVED (BIT(MGMT_ADDR_BREDR) | \
BIT(MGMT_ADDR_LE_PUBLIC) | \
BIT(MGMT_ADDR_LE_RANDOM))
#define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR))
#define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \
BIT(BDADDR_LE_RANDOM))
#define DISCOV_TYPE_INTERLEAVED (BIT(BDADDR_BREDR) | \
BIT(BDADDR_LE_PUBLIC) | \
BIT(BDADDR_LE_RANDOM))
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_index_added(struct hci_dev *hdev);
@@ -1067,12 +1072,12 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier);
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
__u8 ltk[16]);
void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
void hci_le_ltk_neg_reply(struct hci_conn *conn);
int hci_do_inquiry(struct hci_dev *hdev, u8 length);
int hci_cancel_inquiry(struct hci_dev *hdev);
int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
int timeout);
int hci_cancel_le_scan(struct hci_dev *hdev);
u8 bdaddr_to_le(u8 bdaddr_type);
#endif /* __HCI_CORE_H */
+79 -14
View File
@@ -44,6 +44,7 @@
#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
#define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF
#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF
#define L2CAP_BREDR_MAX_PAYLOAD 1019 /* 3-DH5 packet */
#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100)
#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000)
@@ -57,6 +58,7 @@ struct sockaddr_l2 {
__le16 l2_psm;
bdaddr_t l2_bdaddr;
__le16 l2_cid;
__u8 l2_bdaddr_type;
};
/* L2CAP socket options */
@@ -139,6 +141,8 @@ struct l2cap_conninfo {
#define L2CAP_CTRL_TXSEQ_SHIFT 1
#define L2CAP_CTRL_SUPER_SHIFT 2
#define L2CAP_CTRL_POLL_SHIFT 4
#define L2CAP_CTRL_FINAL_SHIFT 7
#define L2CAP_CTRL_REQSEQ_SHIFT 8
#define L2CAP_CTRL_SAR_SHIFT 14
@@ -152,9 +156,11 @@ struct l2cap_conninfo {
#define L2CAP_EXT_CTRL_FINAL 0x00000002
#define L2CAP_EXT_CTRL_FRAME_TYPE 0x00000001 /* I- or S-Frame */
#define L2CAP_EXT_CTRL_FINAL_SHIFT 1
#define L2CAP_EXT_CTRL_REQSEQ_SHIFT 2
#define L2CAP_EXT_CTRL_SAR_SHIFT 16
#define L2CAP_EXT_CTRL_SUPER_SHIFT 16
#define L2CAP_EXT_CTRL_POLL_SHIFT 18
#define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18
/* L2CAP Supervisory Function */
@@ -186,6 +192,8 @@ struct l2cap_hdr {
#define L2CAP_FCS_SIZE 2
#define L2CAP_SDULEN_SIZE 2
#define L2CAP_PSMLEN_SIZE 2
#define L2CAP_ENH_CTRL_SIZE 2
#define L2CAP_EXT_CTRL_SIZE 4
struct l2cap_cmd_hdr {
__u8 code;
@@ -401,6 +409,16 @@ struct l2cap_conn_param_update_rsp {
#define L2CAP_CONN_PARAM_REJECTED 0x0001
/* ----- L2CAP channels and connections ----- */
struct l2cap_seq_list {
__u16 head;
__u16 tail;
__u16 mask;
__u16 *list;
};
#define L2CAP_SEQ_LIST_CLEAR 0xFFFF
#define L2CAP_SEQ_LIST_TAIL 0x8000
struct srej_list {
__u16 tx_seq;
struct list_head list;
@@ -446,6 +464,9 @@ struct l2cap_chan {
__u16 monitor_timeout;
__u16 mps;
__u8 tx_state;
__u8 rx_state;
unsigned long conf_state;
unsigned long conn_state;
unsigned long flags;
@@ -456,9 +477,11 @@ struct l2cap_chan {
__u16 buffer_seq;
__u16 buffer_seq_srej;
__u16 srej_save_reqseq;
__u16 last_acked_seq;
__u16 frames_sent;
__u16 unacked_frames;
__u8 retry_count;
__u16 srej_queue_next;
__u8 num_acked;
__u16 sdu_len;
struct sk_buff *sdu;
@@ -490,6 +513,8 @@ struct l2cap_chan {
struct sk_buff *tx_send_head;
struct sk_buff_head tx_q;
struct sk_buff_head srej_q;
struct l2cap_seq_list srej_list;
struct l2cap_seq_list retrans_list;
struct list_head srej_l;
struct list_head list;
@@ -508,8 +533,7 @@ struct l2cap_ops {
void (*close) (void *data);
void (*state_change) (void *data, int state);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb, int *err);
unsigned long len, int nb);
};
struct l2cap_conn {
@@ -600,6 +624,44 @@ enum {
FLAG_EFS_ENABLE,
};
enum {
L2CAP_TX_STATE_XMIT,
L2CAP_TX_STATE_WAIT_F,
};
enum {
L2CAP_RX_STATE_RECV,
L2CAP_RX_STATE_SREJ_SENT,
};
enum {
L2CAP_TXSEQ_EXPECTED,
L2CAP_TXSEQ_EXPECTED_SREJ,
L2CAP_TXSEQ_UNEXPECTED,
L2CAP_TXSEQ_UNEXPECTED_SREJ,
L2CAP_TXSEQ_DUPLICATE,
L2CAP_TXSEQ_DUPLICATE_SREJ,
L2CAP_TXSEQ_INVALID,
L2CAP_TXSEQ_INVALID_IGNORE,
};
enum {
L2CAP_EV_DATA_REQUEST,
L2CAP_EV_LOCAL_BUSY_DETECTED,
L2CAP_EV_LOCAL_BUSY_CLEAR,
L2CAP_EV_RECV_REQSEQ_AND_FBIT,
L2CAP_EV_RECV_FBIT,
L2CAP_EV_RETRANS_TO,
L2CAP_EV_MONITOR_TO,
L2CAP_EV_EXPLICIT_POLL,
L2CAP_EV_RECV_IFRAME,
L2CAP_EV_RECV_RR,
L2CAP_EV_RECV_REJ,
L2CAP_EV_RECV_RNR,
L2CAP_EV_RECV_SREJ,
L2CAP_EV_RECV_FRAME,
};
static inline void l2cap_chan_hold(struct l2cap_chan *c)
{
atomic_inc(&c->refcnt);
@@ -622,21 +684,26 @@ static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
}
static inline void l2cap_set_timer(struct l2cap_chan *chan,
struct delayed_work *work, long timeout)
struct delayed_work *work, long timeout)
{
BT_DBG("chan %p state %s timeout %ld", chan,
state_to_string(chan->state), timeout);
state_to_string(chan->state), timeout);
/* If delayed work cancelled do not hold(chan)
since it is already done with previous set_timer */
if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
struct delayed_work *work)
struct delayed_work *work)
{
bool ret;
/* put(chan) if delayed work cancelled otherwise it
is done in delayed work function */
ret = cancel_delayed_work(work);
if (ret)
l2cap_chan_put(chan);
@@ -658,13 +725,10 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
{
int offset;
offset = (seq1 - seq2) % (chan->tx_win_max + 1);
if (offset < 0)
offset += (chan->tx_win_max + 1);
return offset;
if (seq1 >= seq2)
return seq1 - seq2;
else
return chan->tx_win_max + 1 - seq2 + seq1;
}
static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq)
@@ -852,14 +916,15 @@ int __l2cap_wait_ack(struct sock *sk);
int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
struct l2cap_chan *l2cap_chan_create(void);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst);
bdaddr_t *dst, u8 dst_type);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
u32 priority);
void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
int l2cap_chan_check_security(struct l2cap_chan *chan);
void l2cap_chan_set_defaults(struct l2cap_chan *chan);
#endif /* __L2CAP_H */
+9
View File
@@ -341,6 +341,15 @@ struct mgmt_cp_unblock_device {
} __packed;
#define MGMT_UNBLOCK_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_SET_DEVICE_ID 0x0028
struct mgmt_cp_set_device_id {
__le16 source;
__le16 vendor;
__le16 product;
__le16 version;
} __packed;
#define MGMT_SET_DEVICE_ID_SIZE 8
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
+1 -1
View File
@@ -77,7 +77,7 @@ struct smp_cmd_encrypt_info {
#define SMP_CMD_MASTER_IDENT 0x07
struct smp_cmd_master_ident {
__u16 ediv;
__le16 ediv;
__u8 rand[8];
} __packed;