diff options
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 29 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 22 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 136 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 416 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt.h | 47 |
5 files changed, 539 insertions, 111 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index e86af08293a8..835f3b229b84 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -77,6 +77,33 @@ struct bt_power { | |||
77 | #define BT_POWER_FORCE_ACTIVE_OFF 0 | 77 | #define BT_POWER_FORCE_ACTIVE_OFF 0 |
78 | #define BT_POWER_FORCE_ACTIVE_ON 1 | 78 | #define BT_POWER_FORCE_ACTIVE_ON 1 |
79 | 79 | ||
80 | #define BT_CHANNEL_POLICY 10 | ||
81 | |||
82 | /* BR/EDR only (default policy) | ||
83 | * AMP controllers cannot be used. | ||
84 | * Channel move requests from the remote device are denied. | ||
85 | * If the L2CAP channel is currently using AMP, move the channel to BR/EDR. | ||
86 | */ | ||
87 | #define BT_CHANNEL_POLICY_BREDR_ONLY 0 | ||
88 | |||
89 | /* BR/EDR Preferred | ||
90 | * Allow use of AMP controllers. | ||
91 | * If the L2CAP channel is currently on AMP, move it to BR/EDR. | ||
92 | * Channel move requests from the remote device are allowed. | ||
93 | */ | ||
94 | #define BT_CHANNEL_POLICY_BREDR_PREFERRED 1 | ||
95 | |||
96 | /* AMP Preferred | ||
97 | * Allow use of AMP controllers | ||
98 | * If the L2CAP channel is currently on BR/EDR and AMP controller | ||
99 | * resources are available, initiate a channel move to AMP. | ||
100 | * Channel move requests from the remote device are allowed. | ||
101 | * If the L2CAP socket has not been connected yet, try to create | ||
102 | * and configure the channel directly on an AMP controller rather | ||
103 | * than BR/EDR. | ||
104 | */ | ||
105 | #define BT_CHANNEL_POLICY_AMP_PREFERRED 2 | ||
106 | |||
80 | __printf(2, 3) | 107 | __printf(2, 3) |
81 | int bt_printk(const char *level, const char *fmt, ...); | 108 | int bt_printk(const char *level, const char *fmt, ...); |
82 | 109 | ||
@@ -158,7 +185,7 @@ struct bt_skb_cb { | |||
158 | __u8 pkt_type; | 185 | __u8 pkt_type; |
159 | __u8 incoming; | 186 | __u8 incoming; |
160 | __u16 expect; | 187 | __u16 expect; |
161 | __u8 tx_seq; | 188 | __u16 tx_seq; |
162 | __u8 retries; | 189 | __u8 retries; |
163 | __u8 sar; | 190 | __u8 sar; |
164 | unsigned short channel; | 191 | unsigned short channel; |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index aaf79af72432..139ce2aa6eee 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -264,6 +264,13 @@ enum { | |||
264 | #define HCI_LK_SMP_IRK 0x82 | 264 | #define HCI_LK_SMP_IRK 0x82 |
265 | #define HCI_LK_SMP_CSRK 0x83 | 265 | #define HCI_LK_SMP_CSRK 0x83 |
266 | 266 | ||
267 | /* ---- HCI Error Codes ---- */ | ||
268 | #define HCI_ERROR_AUTH_FAILURE 0x05 | ||
269 | #define HCI_ERROR_REJ_BAD_ADDR 0x0f | ||
270 | #define HCI_ERROR_REMOTE_USER_TERM 0x13 | ||
271 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 | ||
272 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 | ||
273 | |||
267 | /* ----- HCI Commands ---- */ | 274 | /* ----- HCI Commands ---- */ |
268 | #define HCI_OP_NOP 0x0000 | 275 | #define HCI_OP_NOP 0x0000 |
269 | 276 | ||
@@ -726,6 +733,21 @@ struct hci_cp_write_page_scan_activity { | |||
726 | #define PAGE_SCAN_TYPE_STANDARD 0x00 | 733 | #define PAGE_SCAN_TYPE_STANDARD 0x00 |
727 | #define PAGE_SCAN_TYPE_INTERLACED 0x01 | 734 | #define PAGE_SCAN_TYPE_INTERLACED 0x01 |
728 | 735 | ||
736 | #define HCI_OP_READ_LOCAL_AMP_INFO 0x1409 | ||
737 | struct hci_rp_read_local_amp_info { | ||
738 | __u8 status; | ||
739 | __u8 amp_status; | ||
740 | __le32 total_bw; | ||
741 | __le32 max_bw; | ||
742 | __le32 min_latency; | ||
743 | __le32 max_pdu; | ||
744 | __u8 amp_type; | ||
745 | __le16 pal_cap; | ||
746 | __le16 max_assoc_size; | ||
747 | __le32 max_flush_to; | ||
748 | __le32 be_flush_to; | ||
749 | } __packed; | ||
750 | |||
729 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 | 751 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 |
730 | struct hci_cp_le_set_event_mask { | 752 | struct hci_cp_le_set_event_mask { |
731 | __u8 mask[8]; | 753 | __u8 mask[8]; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3779ea362257..f333e7682607 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -32,6 +32,9 @@ | |||
32 | #define HCI_PROTO_L2CAP 0 | 32 | #define HCI_PROTO_L2CAP 0 |
33 | #define HCI_PROTO_SCO 1 | 33 | #define HCI_PROTO_SCO 1 |
34 | 34 | ||
35 | /* HCI priority */ | ||
36 | #define HCI_PRIO_MAX 7 | ||
37 | |||
35 | /* HCI Core structures */ | 38 | /* HCI Core structures */ |
36 | struct inquiry_data { | 39 | struct inquiry_data { |
37 | bdaddr_t bdaddr; | 40 | bdaddr_t bdaddr; |
@@ -64,6 +67,12 @@ struct hci_conn_hash { | |||
64 | unsigned int le_num; | 67 | unsigned int le_num; |
65 | }; | 68 | }; |
66 | 69 | ||
70 | struct hci_chan_hash { | ||
71 | struct list_head list; | ||
72 | spinlock_t lock; | ||
73 | unsigned int num; | ||
74 | }; | ||
75 | |||
67 | struct bdaddr_list { | 76 | struct bdaddr_list { |
68 | struct list_head list; | 77 | struct list_head list; |
69 | bdaddr_t bdaddr; | 78 | bdaddr_t bdaddr; |
@@ -150,6 +159,17 @@ struct hci_dev { | |||
150 | __u16 sniff_min_interval; | 159 | __u16 sniff_min_interval; |
151 | __u16 sniff_max_interval; | 160 | __u16 sniff_max_interval; |
152 | 161 | ||
162 | __u8 amp_status; | ||
163 | __u32 amp_total_bw; | ||
164 | __u32 amp_max_bw; | ||
165 | __u32 amp_min_latency; | ||
166 | __u32 amp_max_pdu; | ||
167 | __u8 amp_type; | ||
168 | __u16 amp_pal_cap; | ||
169 | __u16 amp_assoc_size; | ||
170 | __u32 amp_max_flush_to; | ||
171 | __u32 amp_be_flush_to; | ||
172 | |||
153 | unsigned int auto_accept_delay; | 173 | unsigned int auto_accept_delay; |
154 | 174 | ||
155 | unsigned long quirks; | 175 | unsigned long quirks; |
@@ -173,8 +193,10 @@ struct hci_dev { | |||
173 | struct workqueue_struct *workqueue; | 193 | struct workqueue_struct *workqueue; |
174 | 194 | ||
175 | struct work_struct power_on; | 195 | struct work_struct power_on; |
176 | struct work_struct power_off; | 196 | struct delayed_work power_off; |
177 | struct timer_list off_timer; | 197 | |
198 | __u16 discov_timeout; | ||
199 | struct delayed_work discov_off; | ||
178 | 200 | ||
179 | struct timer_list cmd_timer; | 201 | struct timer_list cmd_timer; |
180 | struct tasklet_struct cmd_task; | 202 | struct tasklet_struct cmd_task; |
@@ -195,6 +217,8 @@ struct hci_dev { | |||
195 | 217 | ||
196 | __u16 init_last_cmd; | 218 | __u16 init_last_cmd; |
197 | 219 | ||
220 | struct list_head mgmt_pending; | ||
221 | |||
198 | struct inquiry_cache inq_cache; | 222 | struct inquiry_cache inq_cache; |
199 | struct hci_conn_hash conn_hash; | 223 | struct hci_conn_hash conn_hash; |
200 | struct list_head blacklist; | 224 | struct list_head blacklist; |
@@ -273,6 +297,7 @@ struct hci_conn { | |||
273 | unsigned int sent; | 297 | unsigned int sent; |
274 | 298 | ||
275 | struct sk_buff_head data_q; | 299 | struct sk_buff_head data_q; |
300 | struct hci_chan_hash chan_hash; | ||
276 | 301 | ||
277 | struct timer_list disc_timer; | 302 | struct timer_list disc_timer; |
278 | struct timer_list idle_timer; | 303 | struct timer_list idle_timer; |
@@ -295,6 +320,14 @@ struct hci_conn { | |||
295 | void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); | 320 | void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); |
296 | }; | 321 | }; |
297 | 322 | ||
323 | struct hci_chan { | ||
324 | struct list_head list; | ||
325 | |||
326 | struct hci_conn *conn; | ||
327 | struct sk_buff_head data_q; | ||
328 | unsigned int sent; | ||
329 | }; | ||
330 | |||
298 | extern struct hci_proto *hci_proto[]; | 331 | extern struct hci_proto *hci_proto[]; |
299 | extern struct list_head hci_dev_list; | 332 | extern struct list_head hci_dev_list; |
300 | extern struct list_head hci_cb_list; | 333 | extern struct list_head hci_cb_list; |
@@ -455,6 +488,28 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | |||
455 | return NULL; | 488 | return NULL; |
456 | } | 489 | } |
457 | 490 | ||
491 | static inline void hci_chan_hash_init(struct hci_conn *c) | ||
492 | { | ||
493 | struct hci_chan_hash *h = &c->chan_hash; | ||
494 | INIT_LIST_HEAD(&h->list); | ||
495 | spin_lock_init(&h->lock); | ||
496 | h->num = 0; | ||
497 | } | ||
498 | |||
499 | static inline void hci_chan_hash_add(struct hci_conn *c, struct hci_chan *chan) | ||
500 | { | ||
501 | struct hci_chan_hash *h = &c->chan_hash; | ||
502 | list_add(&chan->list, &h->list); | ||
503 | h->num++; | ||
504 | } | ||
505 | |||
506 | static inline void hci_chan_hash_del(struct hci_conn *c, struct hci_chan *chan) | ||
507 | { | ||
508 | struct hci_chan_hash *h = &c->chan_hash; | ||
509 | list_del(&chan->list); | ||
510 | h->num--; | ||
511 | } | ||
512 | |||
458 | void hci_acl_connect(struct hci_conn *conn); | 513 | void hci_acl_connect(struct hci_conn *conn); |
459 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); | 514 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); |
460 | void hci_add_sco(struct hci_conn *conn, __u16 handle); | 515 | void hci_add_sco(struct hci_conn *conn, __u16 handle); |
@@ -466,6 +521,10 @@ int hci_conn_del(struct hci_conn *conn); | |||
466 | void hci_conn_hash_flush(struct hci_dev *hdev); | 521 | void hci_conn_hash_flush(struct hci_dev *hdev); |
467 | void hci_conn_check_pending(struct hci_dev *hdev); | 522 | void hci_conn_check_pending(struct hci_dev *hdev); |
468 | 523 | ||
524 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | ||
525 | int hci_chan_del(struct hci_chan *chan); | ||
526 | void hci_chan_hash_flush(struct hci_conn *conn); | ||
527 | |||
469 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 528 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
470 | __u8 sec_level, __u8 auth_type); | 529 | __u8 sec_level, __u8 auth_type); |
471 | int hci_conn_check_link_mode(struct hci_conn *conn); | 530 | int hci_conn_check_link_mode(struct hci_conn *conn); |
@@ -545,7 +604,7 @@ struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); | |||
545 | struct hci_dev *hci_alloc_dev(void); | 604 | struct hci_dev *hci_alloc_dev(void); |
546 | void hci_free_dev(struct hci_dev *hdev); | 605 | void hci_free_dev(struct hci_dev *hdev); |
547 | int hci_register_dev(struct hci_dev *hdev); | 606 | int hci_register_dev(struct hci_dev *hdev); |
548 | int hci_unregister_dev(struct hci_dev *hdev); | 607 | void hci_unregister_dev(struct hci_dev *hdev); |
549 | int hci_suspend_dev(struct hci_dev *hdev); | 608 | int hci_suspend_dev(struct hci_dev *hdev); |
550 | int hci_resume_dev(struct hci_dev *hdev); | 609 | int hci_resume_dev(struct hci_dev *hdev); |
551 | int hci_dev_open(__u16 dev); | 610 | int hci_dev_open(__u16 dev); |
@@ -599,8 +658,9 @@ int hci_recv_frame(struct sk_buff *skb); | |||
599 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); | 658 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); |
600 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); | 659 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); |
601 | 660 | ||
602 | int hci_register_sysfs(struct hci_dev *hdev); | 661 | void hci_init_sysfs(struct hci_dev *hdev); |
603 | void hci_unregister_sysfs(struct hci_dev *hdev); | 662 | int hci_add_sysfs(struct hci_dev *hdev); |
663 | void hci_del_sysfs(struct hci_dev *hdev); | ||
604 | void hci_conn_init_sysfs(struct hci_conn *conn); | 664 | void hci_conn_init_sysfs(struct hci_conn *conn); |
605 | void hci_conn_add_sysfs(struct hci_conn *conn); | 665 | void hci_conn_add_sysfs(struct hci_conn *conn); |
606 | void hci_conn_del_sysfs(struct hci_conn *conn); | 666 | void hci_conn_del_sysfs(struct hci_conn *conn); |
@@ -676,7 +736,7 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | |||
676 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) | 736 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) |
677 | { | 737 | { |
678 | register struct hci_proto *hp; | 738 | register struct hci_proto *hp; |
679 | int reason = 0x13; | 739 | int reason = HCI_ERROR_REMOTE_USER_TERM; |
680 | 740 | ||
681 | hp = hci_proto[HCI_PROTO_L2CAP]; | 741 | hp = hci_proto[HCI_PROTO_L2CAP]; |
682 | if (hp && hp->disconn_ind) | 742 | if (hp && hp->disconn_ind) |
@@ -836,7 +896,7 @@ int hci_register_notifier(struct notifier_block *nb); | |||
836 | int hci_unregister_notifier(struct notifier_block *nb); | 896 | int hci_unregister_notifier(struct notifier_block *nb); |
837 | 897 | ||
838 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); | 898 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); |
839 | void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | 899 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); |
840 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); | 900 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); |
841 | 901 | ||
842 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); | 902 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); |
@@ -849,34 +909,41 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, | |||
849 | 909 | ||
850 | /* Management interface */ | 910 | /* Management interface */ |
851 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 911 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
852 | int mgmt_index_added(u16 index); | 912 | int mgmt_index_added(struct hci_dev *hdev); |
853 | int mgmt_index_removed(u16 index); | 913 | int mgmt_index_removed(struct hci_dev *hdev); |
854 | int mgmt_powered(u16 index, u8 powered); | 914 | int mgmt_powered(struct hci_dev *hdev, u8 powered); |
855 | int mgmt_discoverable(u16 index, u8 discoverable); | 915 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); |
856 | int mgmt_connectable(u16 index, u8 connectable); | 916 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable); |
857 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent); | 917 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); |
858 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type); | 918 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, |
859 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); | 919 | u8 persistent); |
860 | int mgmt_disconnect_failed(u16 index); | 920 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
861 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); | 921 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
862 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure); | 922 | int mgmt_disconnect_failed(struct hci_dev *hdev); |
863 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 923 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
864 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
865 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | ||
866 | u8 confirm_hint); | ||
867 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
868 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, | ||
869 | u8 status); | 924 | u8 status); |
870 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); | 925 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); |
871 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); | 926 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
872 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | ||
873 | u8 status); | 927 | u8 status); |
874 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | 928 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
875 | u8 *eir); | 929 | u8 status); |
876 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); | 930 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
877 | int mgmt_discovering(u16 index, u8 discovering); | 931 | __le32 value, u8 confirm_hint); |
878 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr); | 932 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
879 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr); | 933 | u8 status); |
934 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, | ||
935 | bdaddr_t *bdaddr, u8 status); | ||
936 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status); | ||
937 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); | ||
938 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | ||
939 | u8 *randomizer, u8 status); | ||
940 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, | ||
941 | u8 *dev_class, s8 rssi, u8 *eir); | ||
942 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name); | ||
943 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status); | ||
944 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering); | ||
945 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
946 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
880 | 947 | ||
881 | /* HCI info for socket */ | 948 | /* HCI info for socket */ |
882 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 949 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
@@ -915,4 +982,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | |||
915 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); | 982 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); |
916 | void hci_le_ltk_neg_reply(struct hci_conn *conn); | 983 | void hci_le_ltk_neg_reply(struct hci_conn *conn); |
917 | 984 | ||
985 | int hci_do_inquiry(struct hci_dev *hdev, u8 length); | ||
986 | int hci_cancel_inquiry(struct hci_dev *hdev); | ||
987 | |||
918 | #endif /* __HCI_CORE_H */ | 988 | #endif /* __HCI_CORE_H */ |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ab90ae0970a6..875021ad0675 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -27,20 +27,29 @@ | |||
27 | #ifndef __L2CAP_H | 27 | #ifndef __L2CAP_H |
28 | #define __L2CAP_H | 28 | #define __L2CAP_H |
29 | 29 | ||
30 | #include <asm/unaligned.h> | ||
31 | |||
30 | /* L2CAP defaults */ | 32 | /* L2CAP defaults */ |
31 | #define L2CAP_DEFAULT_MTU 672 | 33 | #define L2CAP_DEFAULT_MTU 672 |
32 | #define L2CAP_DEFAULT_MIN_MTU 48 | 34 | #define L2CAP_DEFAULT_MIN_MTU 48 |
33 | #define L2CAP_DEFAULT_FLUSH_TO 0xffff | 35 | #define L2CAP_DEFAULT_FLUSH_TO 0xffff |
34 | #define L2CAP_DEFAULT_TX_WINDOW 63 | 36 | #define L2CAP_DEFAULT_TX_WINDOW 63 |
37 | #define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF | ||
35 | #define L2CAP_DEFAULT_MAX_TX 3 | 38 | #define L2CAP_DEFAULT_MAX_TX 3 |
36 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ | 39 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ |
37 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ | 40 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ |
38 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ | 41 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ |
39 | #define L2CAP_DEFAULT_ACK_TO 200 | 42 | #define L2CAP_DEFAULT_ACK_TO 200 |
40 | #define L2CAP_LE_DEFAULT_MTU 23 | 43 | #define L2CAP_LE_DEFAULT_MTU 23 |
44 | #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF | ||
45 | #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF | ||
46 | #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF | ||
41 | 47 | ||
42 | #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ | 48 | #define L2CAP_DISC_TIMEOUT (100) |
43 | #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ | 49 | #define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */ |
50 | #define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */ | ||
51 | #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ | ||
52 | #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ | ||
44 | 53 | ||
45 | /* L2CAP socket address */ | 54 | /* L2CAP socket address */ |
46 | struct sockaddr_l2 { | 55 | struct sockaddr_l2 { |
@@ -88,52 +97,82 @@ struct l2cap_conninfo { | |||
88 | #define L2CAP_ECHO_RSP 0x09 | 97 | #define L2CAP_ECHO_RSP 0x09 |
89 | #define L2CAP_INFO_REQ 0x0a | 98 | #define L2CAP_INFO_REQ 0x0a |
90 | #define L2CAP_INFO_RSP 0x0b | 99 | #define L2CAP_INFO_RSP 0x0b |
100 | #define L2CAP_CREATE_CHAN_REQ 0x0c | ||
101 | #define L2CAP_CREATE_CHAN_RSP 0x0d | ||
102 | #define L2CAP_MOVE_CHAN_REQ 0x0e | ||
103 | #define L2CAP_MOVE_CHAN_RSP 0x0f | ||
104 | #define L2CAP_MOVE_CHAN_CFM 0x10 | ||
105 | #define L2CAP_MOVE_CHAN_CFM_RSP 0x11 | ||
91 | #define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 | 106 | #define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 |
92 | #define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 | 107 | #define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 |
93 | 108 | ||
94 | /* L2CAP feature mask */ | 109 | /* L2CAP extended feature mask */ |
95 | #define L2CAP_FEAT_FLOWCTL 0x00000001 | 110 | #define L2CAP_FEAT_FLOWCTL 0x00000001 |
96 | #define L2CAP_FEAT_RETRANS 0x00000002 | 111 | #define L2CAP_FEAT_RETRANS 0x00000002 |
112 | #define L2CAP_FEAT_BIDIR_QOS 0x00000004 | ||
97 | #define L2CAP_FEAT_ERTM 0x00000008 | 113 | #define L2CAP_FEAT_ERTM 0x00000008 |
98 | #define L2CAP_FEAT_STREAMING 0x00000010 | 114 | #define L2CAP_FEAT_STREAMING 0x00000010 |
99 | #define L2CAP_FEAT_FCS 0x00000020 | 115 | #define L2CAP_FEAT_FCS 0x00000020 |
116 | #define L2CAP_FEAT_EXT_FLOW 0x00000040 | ||
100 | #define L2CAP_FEAT_FIXED_CHAN 0x00000080 | 117 | #define L2CAP_FEAT_FIXED_CHAN 0x00000080 |
118 | #define L2CAP_FEAT_EXT_WINDOW 0x00000100 | ||
119 | #define L2CAP_FEAT_UCD 0x00000200 | ||
101 | 120 | ||
102 | /* L2CAP checksum option */ | 121 | /* L2CAP checksum option */ |
103 | #define L2CAP_FCS_NONE 0x00 | 122 | #define L2CAP_FCS_NONE 0x00 |
104 | #define L2CAP_FCS_CRC16 0x01 | 123 | #define L2CAP_FCS_CRC16 0x01 |
105 | 124 | ||
125 | /* L2CAP fixed channels */ | ||
126 | #define L2CAP_FC_L2CAP 0x02 | ||
127 | #define L2CAP_FC_A2MP 0x08 | ||
128 | |||
106 | /* L2CAP Control Field bit masks */ | 129 | /* L2CAP Control Field bit masks */ |
107 | #define L2CAP_CTRL_SAR 0xC000 | 130 | #define L2CAP_CTRL_SAR 0xC000 |
108 | #define L2CAP_CTRL_REQSEQ 0x3F00 | 131 | #define L2CAP_CTRL_REQSEQ 0x3F00 |
109 | #define L2CAP_CTRL_TXSEQ 0x007E | 132 | #define L2CAP_CTRL_TXSEQ 0x007E |
110 | #define L2CAP_CTRL_RETRANS 0x0080 | 133 | #define L2CAP_CTRL_SUPERVISE 0x000C |
111 | #define L2CAP_CTRL_FINAL 0x0080 | 134 | |
112 | #define L2CAP_CTRL_POLL 0x0010 | 135 | #define L2CAP_CTRL_RETRANS 0x0080 |
113 | #define L2CAP_CTRL_SUPERVISE 0x000C | 136 | #define L2CAP_CTRL_FINAL 0x0080 |
114 | #define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */ | 137 | #define L2CAP_CTRL_POLL 0x0010 |
115 | 138 | #define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */ | |
116 | #define L2CAP_CTRL_TXSEQ_SHIFT 1 | 139 | |
117 | #define L2CAP_CTRL_REQSEQ_SHIFT 8 | 140 | #define L2CAP_CTRL_TXSEQ_SHIFT 1 |
118 | #define L2CAP_CTRL_SAR_SHIFT 14 | 141 | #define L2CAP_CTRL_SUPER_SHIFT 2 |
142 | #define L2CAP_CTRL_REQSEQ_SHIFT 8 | ||
143 | #define L2CAP_CTRL_SAR_SHIFT 14 | ||
144 | |||
145 | /* L2CAP Extended Control Field bit mask */ | ||
146 | #define L2CAP_EXT_CTRL_TXSEQ 0xFFFC0000 | ||
147 | #define L2CAP_EXT_CTRL_SAR 0x00030000 | ||
148 | #define L2CAP_EXT_CTRL_SUPERVISE 0x00030000 | ||
149 | #define L2CAP_EXT_CTRL_REQSEQ 0x0000FFFC | ||
150 | |||
151 | #define L2CAP_EXT_CTRL_POLL 0x00040000 | ||
152 | #define L2CAP_EXT_CTRL_FINAL 0x00000002 | ||
153 | #define L2CAP_EXT_CTRL_FRAME_TYPE 0x00000001 /* I- or S-Frame */ | ||
154 | |||
155 | #define L2CAP_EXT_CTRL_REQSEQ_SHIFT 2 | ||
156 | #define L2CAP_EXT_CTRL_SAR_SHIFT 16 | ||
157 | #define L2CAP_EXT_CTRL_SUPER_SHIFT 16 | ||
158 | #define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18 | ||
119 | 159 | ||
120 | /* L2CAP Supervisory Function */ | 160 | /* L2CAP Supervisory Function */ |
121 | #define L2CAP_SUPER_RCV_READY 0x0000 | 161 | #define L2CAP_SUPER_RR 0x00 |
122 | #define L2CAP_SUPER_REJECT 0x0004 | 162 | #define L2CAP_SUPER_REJ 0x01 |
123 | #define L2CAP_SUPER_RCV_NOT_READY 0x0008 | 163 | #define L2CAP_SUPER_RNR 0x02 |
124 | #define L2CAP_SUPER_SELECT_REJECT 0x000C | 164 | #define L2CAP_SUPER_SREJ 0x03 |
125 | 165 | ||
126 | /* L2CAP Segmentation and Reassembly */ | 166 | /* L2CAP Segmentation and Reassembly */ |
127 | #define L2CAP_SDU_UNSEGMENTED 0x0000 | 167 | #define L2CAP_SAR_UNSEGMENTED 0x00 |
128 | #define L2CAP_SDU_START 0x4000 | 168 | #define L2CAP_SAR_START 0x01 |
129 | #define L2CAP_SDU_END 0x8000 | 169 | #define L2CAP_SAR_END 0x02 |
130 | #define L2CAP_SDU_CONTINUE 0xC000 | 170 | #define L2CAP_SAR_CONTINUE 0x03 |
131 | 171 | ||
132 | /* L2CAP Command rej. reasons */ | 172 | /* L2CAP Command rej. reasons */ |
133 | #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 | 173 | #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 |
134 | #define L2CAP_REJ_MTU_EXCEEDED 0x0001 | 174 | #define L2CAP_REJ_MTU_EXCEEDED 0x0001 |
135 | #define L2CAP_REJ_INVALID_CID 0x0002 | 175 | #define L2CAP_REJ_INVALID_CID 0x0002 |
136 | |||
137 | 176 | ||
138 | /* L2CAP structures */ | 177 | /* L2CAP structures */ |
139 | struct l2cap_hdr { | 178 | struct l2cap_hdr { |
@@ -141,6 +180,12 @@ struct l2cap_hdr { | |||
141 | __le16 cid; | 180 | __le16 cid; |
142 | } __packed; | 181 | } __packed; |
143 | #define L2CAP_HDR_SIZE 4 | 182 | #define L2CAP_HDR_SIZE 4 |
183 | #define L2CAP_ENH_HDR_SIZE 6 | ||
184 | #define L2CAP_EXT_HDR_SIZE 8 | ||
185 | |||
186 | #define L2CAP_FCS_SIZE 2 | ||
187 | #define L2CAP_SDULEN_SIZE 2 | ||
188 | #define L2CAP_PSMLEN_SIZE 2 | ||
144 | 189 | ||
145 | struct l2cap_cmd_hdr { | 190 | struct l2cap_cmd_hdr { |
146 | __u8 code; | 191 | __u8 code; |
@@ -185,14 +230,15 @@ struct l2cap_conn_rsp { | |||
185 | #define L2CAP_CID_DYN_START 0x0040 | 230 | #define L2CAP_CID_DYN_START 0x0040 |
186 | #define L2CAP_CID_DYN_END 0xffff | 231 | #define L2CAP_CID_DYN_END 0xffff |
187 | 232 | ||
188 | /* connect result */ | 233 | /* connect/create channel results */ |
189 | #define L2CAP_CR_SUCCESS 0x0000 | 234 | #define L2CAP_CR_SUCCESS 0x0000 |
190 | #define L2CAP_CR_PEND 0x0001 | 235 | #define L2CAP_CR_PEND 0x0001 |
191 | #define L2CAP_CR_BAD_PSM 0x0002 | 236 | #define L2CAP_CR_BAD_PSM 0x0002 |
192 | #define L2CAP_CR_SEC_BLOCK 0x0003 | 237 | #define L2CAP_CR_SEC_BLOCK 0x0003 |
193 | #define L2CAP_CR_NO_MEM 0x0004 | 238 | #define L2CAP_CR_NO_MEM 0x0004 |
239 | #define L2CAP_CR_BAD_AMP 0x0005 | ||
194 | 240 | ||
195 | /* connect status */ | 241 | /* connect/create channel status */ |
196 | #define L2CAP_CS_NO_INFO 0x0000 | 242 | #define L2CAP_CS_NO_INFO 0x0000 |
197 | #define L2CAP_CS_AUTHEN_PEND 0x0001 | 243 | #define L2CAP_CS_AUTHEN_PEND 0x0001 |
198 | #define L2CAP_CS_AUTHOR_PEND 0x0002 | 244 | #define L2CAP_CS_AUTHOR_PEND 0x0002 |
@@ -214,6 +260,8 @@ struct l2cap_conf_rsp { | |||
214 | #define L2CAP_CONF_UNACCEPT 0x0001 | 260 | #define L2CAP_CONF_UNACCEPT 0x0001 |
215 | #define L2CAP_CONF_REJECT 0x0002 | 261 | #define L2CAP_CONF_REJECT 0x0002 |
216 | #define L2CAP_CONF_UNKNOWN 0x0003 | 262 | #define L2CAP_CONF_UNKNOWN 0x0003 |
263 | #define L2CAP_CONF_PENDING 0x0004 | ||
264 | #define L2CAP_CONF_EFS_REJECT 0x0005 | ||
217 | 265 | ||
218 | struct l2cap_conf_opt { | 266 | struct l2cap_conf_opt { |
219 | __u8 type; | 267 | __u8 type; |
@@ -230,6 +278,8 @@ struct l2cap_conf_opt { | |||
230 | #define L2CAP_CONF_QOS 0x03 | 278 | #define L2CAP_CONF_QOS 0x03 |
231 | #define L2CAP_CONF_RFC 0x04 | 279 | #define L2CAP_CONF_RFC 0x04 |
232 | #define L2CAP_CONF_FCS 0x05 | 280 | #define L2CAP_CONF_FCS 0x05 |
281 | #define L2CAP_CONF_EFS 0x06 | ||
282 | #define L2CAP_CONF_EWS 0x07 | ||
233 | 283 | ||
234 | #define L2CAP_CONF_MAX_SIZE 22 | 284 | #define L2CAP_CONF_MAX_SIZE 22 |
235 | 285 | ||
@@ -248,6 +298,21 @@ struct l2cap_conf_rfc { | |||
248 | #define L2CAP_MODE_ERTM 0x03 | 298 | #define L2CAP_MODE_ERTM 0x03 |
249 | #define L2CAP_MODE_STREAMING 0x04 | 299 | #define L2CAP_MODE_STREAMING 0x04 |
250 | 300 | ||
301 | struct l2cap_conf_efs { | ||
302 | __u8 id; | ||
303 | __u8 stype; | ||
304 | __le16 msdu; | ||
305 | __le32 sdu_itime; | ||
306 | __le32 acc_lat; | ||
307 | __le32 flush_to; | ||
308 | } __packed; | ||
309 | |||
310 | #define L2CAP_SERV_NOTRAFIC 0x00 | ||
311 | #define L2CAP_SERV_BESTEFFORT 0x01 | ||
312 | #define L2CAP_SERV_GUARANTEED 0x02 | ||
313 | |||
314 | #define L2CAP_BESTEFFORT_ID 0x01 | ||
315 | |||
251 | struct l2cap_disconn_req { | 316 | struct l2cap_disconn_req { |
252 | __le16 dcid; | 317 | __le16 dcid; |
253 | __le16 scid; | 318 | __le16 scid; |
@@ -268,14 +333,57 @@ struct l2cap_info_rsp { | |||
268 | __u8 data[0]; | 333 | __u8 data[0]; |
269 | } __packed; | 334 | } __packed; |
270 | 335 | ||
336 | struct l2cap_create_chan_req { | ||
337 | __le16 psm; | ||
338 | __le16 scid; | ||
339 | __u8 amp_id; | ||
340 | } __packed; | ||
341 | |||
342 | struct l2cap_create_chan_rsp { | ||
343 | __le16 dcid; | ||
344 | __le16 scid; | ||
345 | __le16 result; | ||
346 | __le16 status; | ||
347 | } __packed; | ||
348 | |||
349 | struct l2cap_move_chan_req { | ||
350 | __le16 icid; | ||
351 | __u8 dest_amp_id; | ||
352 | } __packed; | ||
353 | |||
354 | struct l2cap_move_chan_rsp { | ||
355 | __le16 icid; | ||
356 | __le16 result; | ||
357 | } __packed; | ||
358 | |||
359 | #define L2CAP_MR_SUCCESS 0x0000 | ||
360 | #define L2CAP_MR_PEND 0x0001 | ||
361 | #define L2CAP_MR_BAD_ID 0x0002 | ||
362 | #define L2CAP_MR_SAME_ID 0x0003 | ||
363 | #define L2CAP_MR_NOT_SUPP 0x0004 | ||
364 | #define L2CAP_MR_COLLISION 0x0005 | ||
365 | #define L2CAP_MR_NOT_ALLOWED 0x0006 | ||
366 | |||
367 | struct l2cap_move_chan_cfm { | ||
368 | __le16 icid; | ||
369 | __le16 result; | ||
370 | } __packed; | ||
371 | |||
372 | #define L2CAP_MC_CONFIRMED 0x0000 | ||
373 | #define L2CAP_MC_UNCONFIRMED 0x0001 | ||
374 | |||
375 | struct l2cap_move_chan_cfm_rsp { | ||
376 | __le16 icid; | ||
377 | } __packed; | ||
378 | |||
271 | /* info type */ | 379 | /* info type */ |
272 | #define L2CAP_IT_CL_MTU 0x0001 | 380 | #define L2CAP_IT_CL_MTU 0x0001 |
273 | #define L2CAP_IT_FEAT_MASK 0x0002 | 381 | #define L2CAP_IT_FEAT_MASK 0x0002 |
274 | #define L2CAP_IT_FIXED_CHAN 0x0003 | 382 | #define L2CAP_IT_FIXED_CHAN 0x0003 |
275 | 383 | ||
276 | /* info result */ | 384 | /* info result */ |
277 | #define L2CAP_IR_SUCCESS 0x0000 | 385 | #define L2CAP_IR_SUCCESS 0x0000 |
278 | #define L2CAP_IR_NOTSUPP 0x0001 | 386 | #define L2CAP_IR_NOTSUPP 0x0001 |
279 | 387 | ||
280 | struct l2cap_conn_param_update_req { | 388 | struct l2cap_conn_param_update_req { |
281 | __le16 min; | 389 | __le16 min; |
@@ -294,7 +402,7 @@ struct l2cap_conn_param_update_rsp { | |||
294 | 402 | ||
295 | /* ----- L2CAP channels and connections ----- */ | 403 | /* ----- L2CAP channels and connections ----- */ |
296 | struct srej_list { | 404 | struct srej_list { |
297 | __u8 tx_seq; | 405 | __u16 tx_seq; |
298 | struct list_head list; | 406 | struct list_head list; |
299 | }; | 407 | }; |
300 | 408 | ||
@@ -316,14 +424,11 @@ struct l2cap_chan { | |||
316 | __u16 flush_to; | 424 | __u16 flush_to; |
317 | __u8 mode; | 425 | __u8 mode; |
318 | __u8 chan_type; | 426 | __u8 chan_type; |
427 | __u8 chan_policy; | ||
319 | 428 | ||
320 | __le16 sport; | 429 | __le16 sport; |
321 | 430 | ||
322 | __u8 sec_level; | 431 | __u8 sec_level; |
323 | __u8 role_switch; | ||
324 | __u8 force_reliable; | ||
325 | __u8 flushable; | ||
326 | __u8 force_active; | ||
327 | 432 | ||
328 | __u8 ident; | 433 | __u8 ident; |
329 | 434 | ||
@@ -334,7 +439,8 @@ struct l2cap_chan { | |||
334 | 439 | ||
335 | __u8 fcs; | 440 | __u8 fcs; |
336 | 441 | ||
337 | __u8 tx_win; | 442 | __u16 tx_win; |
443 | __u16 tx_win_max; | ||
338 | __u8 max_tx; | 444 | __u8 max_tx; |
339 | __u16 retrans_timeout; | 445 | __u16 retrans_timeout; |
340 | __u16 monitor_timeout; | 446 | __u16 monitor_timeout; |
@@ -342,25 +448,40 @@ struct l2cap_chan { | |||
342 | 448 | ||
343 | unsigned long conf_state; | 449 | unsigned long conf_state; |
344 | unsigned long conn_state; | 450 | unsigned long conn_state; |
345 | 451 | unsigned long flags; | |
346 | __u8 next_tx_seq; | 452 | |
347 | __u8 expected_ack_seq; | 453 | __u16 next_tx_seq; |
348 | __u8 expected_tx_seq; | 454 | __u16 expected_ack_seq; |
349 | __u8 buffer_seq; | 455 | __u16 expected_tx_seq; |
350 | __u8 buffer_seq_srej; | 456 | __u16 buffer_seq; |
351 | __u8 srej_save_reqseq; | 457 | __u16 buffer_seq_srej; |
352 | __u8 frames_sent; | 458 | __u16 srej_save_reqseq; |
353 | __u8 unacked_frames; | 459 | __u16 frames_sent; |
460 | __u16 unacked_frames; | ||
354 | __u8 retry_count; | 461 | __u8 retry_count; |
355 | __u8 num_acked; | 462 | __u8 num_acked; |
356 | __u16 sdu_len; | 463 | __u16 sdu_len; |
357 | struct sk_buff *sdu; | 464 | struct sk_buff *sdu; |
358 | struct sk_buff *sdu_last_frag; | 465 | struct sk_buff *sdu_last_frag; |
359 | 466 | ||
360 | __u8 remote_tx_win; | 467 | __u16 remote_tx_win; |
361 | __u8 remote_max_tx; | 468 | __u8 remote_max_tx; |
362 | __u16 remote_mps; | 469 | __u16 remote_mps; |
363 | 470 | ||
471 | __u8 local_id; | ||
472 | __u8 local_stype; | ||
473 | __u16 local_msdu; | ||
474 | __u32 local_sdu_itime; | ||
475 | __u32 local_acc_lat; | ||
476 | __u32 local_flush_to; | ||
477 | |||
478 | __u8 remote_id; | ||
479 | __u8 remote_stype; | ||
480 | __u16 remote_msdu; | ||
481 | __u32 remote_sdu_itime; | ||
482 | __u32 remote_acc_lat; | ||
483 | __u32 remote_flush_to; | ||
484 | |||
364 | struct timer_list chan_timer; | 485 | struct timer_list chan_timer; |
365 | struct timer_list retrans_timer; | 486 | struct timer_list retrans_timer; |
366 | struct timer_list monitor_timer; | 487 | struct timer_list monitor_timer; |
@@ -388,6 +509,7 @@ struct l2cap_ops { | |||
388 | 509 | ||
389 | struct l2cap_conn { | 510 | struct l2cap_conn { |
390 | struct hci_conn *hcon; | 511 | struct hci_conn *hcon; |
512 | struct hci_chan *hchan; | ||
391 | 513 | ||
392 | bdaddr_t *dst; | 514 | bdaddr_t *dst; |
393 | bdaddr_t *src; | 515 | bdaddr_t *src; |
@@ -442,6 +564,9 @@ enum { | |||
442 | CONF_CONNECT_PEND, | 564 | CONF_CONNECT_PEND, |
443 | CONF_NO_FCS_RECV, | 565 | CONF_NO_FCS_RECV, |
444 | CONF_STATE2_DEVICE, | 566 | CONF_STATE2_DEVICE, |
567 | CONF_EWS_RECV, | ||
568 | CONF_LOC_CONF_PEND, | ||
569 | CONF_REM_CONF_PEND, | ||
445 | }; | 570 | }; |
446 | 571 | ||
447 | #define L2CAP_CONF_MAX_CONF_REQ 2 | 572 | #define L2CAP_CONF_MAX_CONF_REQ 2 |
@@ -459,6 +584,16 @@ enum { | |||
459 | CONN_RNR_SENT, | 584 | CONN_RNR_SENT, |
460 | }; | 585 | }; |
461 | 586 | ||
587 | /* Definitions for flags in l2cap_chan */ | ||
588 | enum { | ||
589 | FLAG_ROLE_SWITCH, | ||
590 | FLAG_FORCE_ACTIVE, | ||
591 | FLAG_FORCE_RELIABLE, | ||
592 | FLAG_FLUSHABLE, | ||
593 | FLAG_EXT_CTRL, | ||
594 | FLAG_EFS_ENABLE, | ||
595 | }; | ||
596 | |||
462 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) | 597 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
463 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) | 598 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
464 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ | 599 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ |
@@ -471,6 +606,22 @@ enum { | |||
471 | L2CAP_DEFAULT_ACK_TO); | 606 | L2CAP_DEFAULT_ACK_TO); |
472 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) | 607 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) |
473 | 608 | ||
609 | static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) | ||
610 | { | ||
611 | int offset; | ||
612 | |||
613 | offset = (seq1 - seq2) % (chan->tx_win_max + 1); | ||
614 | if (offset < 0) | ||
615 | offset += (chan->tx_win_max + 1); | ||
616 | |||
617 | return offset; | ||
618 | } | ||
619 | |||
620 | static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) | ||
621 | { | ||
622 | return (seq + 1) % (chan->tx_win_max + 1); | ||
623 | } | ||
624 | |||
474 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | 625 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) |
475 | { | 626 | { |
476 | int sub; | 627 | int sub; |
@@ -483,13 +634,165 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | |||
483 | return sub == ch->remote_tx_win; | 634 | return sub == ch->remote_tx_win; |
484 | } | 635 | } |
485 | 636 | ||
486 | #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) | 637 | static inline __u16 __get_reqseq(struct l2cap_chan *chan, __u32 ctrl) |
487 | #define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8) | 638 | { |
488 | #define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE)) | 639 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) |
489 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) | 640 | return (ctrl & L2CAP_EXT_CTRL_REQSEQ) >> |
490 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 641 | L2CAP_EXT_CTRL_REQSEQ_SHIFT; |
642 | else | ||
643 | return (ctrl & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT; | ||
644 | } | ||
645 | |||
646 | static inline __u32 __set_reqseq(struct l2cap_chan *chan, __u32 reqseq) | ||
647 | { | ||
648 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
649 | return (reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT) & | ||
650 | L2CAP_EXT_CTRL_REQSEQ; | ||
651 | else | ||
652 | return (reqseq << L2CAP_CTRL_REQSEQ_SHIFT) & L2CAP_CTRL_REQSEQ; | ||
653 | } | ||
654 | |||
655 | static inline __u16 __get_txseq(struct l2cap_chan *chan, __u32 ctrl) | ||
656 | { | ||
657 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
658 | return (ctrl & L2CAP_EXT_CTRL_TXSEQ) >> | ||
659 | L2CAP_EXT_CTRL_TXSEQ_SHIFT; | ||
660 | else | ||
661 | return (ctrl & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT; | ||
662 | } | ||
663 | |||
664 | static inline __u32 __set_txseq(struct l2cap_chan *chan, __u32 txseq) | ||
665 | { | ||
666 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
667 | return (txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT) & | ||
668 | L2CAP_EXT_CTRL_TXSEQ; | ||
669 | else | ||
670 | return (txseq << L2CAP_CTRL_TXSEQ_SHIFT) & L2CAP_CTRL_TXSEQ; | ||
671 | } | ||
672 | |||
673 | static inline bool __is_sframe(struct l2cap_chan *chan, __u32 ctrl) | ||
674 | { | ||
675 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
676 | return ctrl & L2CAP_EXT_CTRL_FRAME_TYPE; | ||
677 | else | ||
678 | return ctrl & L2CAP_CTRL_FRAME_TYPE; | ||
679 | } | ||
680 | |||
681 | static inline __u32 __set_sframe(struct l2cap_chan *chan) | ||
682 | { | ||
683 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
684 | return L2CAP_EXT_CTRL_FRAME_TYPE; | ||
685 | else | ||
686 | return L2CAP_CTRL_FRAME_TYPE; | ||
687 | } | ||
688 | |||
689 | static inline __u8 __get_ctrl_sar(struct l2cap_chan *chan, __u32 ctrl) | ||
690 | { | ||
691 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
692 | return (ctrl & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT; | ||
693 | else | ||
694 | return (ctrl & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT; | ||
695 | } | ||
696 | |||
697 | static inline __u32 __set_ctrl_sar(struct l2cap_chan *chan, __u32 sar) | ||
698 | { | ||
699 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
700 | return (sar << L2CAP_EXT_CTRL_SAR_SHIFT) & L2CAP_EXT_CTRL_SAR; | ||
701 | else | ||
702 | return (sar << L2CAP_CTRL_SAR_SHIFT) & L2CAP_CTRL_SAR; | ||
703 | } | ||
704 | |||
705 | static inline bool __is_sar_start(struct l2cap_chan *chan, __u32 ctrl) | ||
706 | { | ||
707 | return __get_ctrl_sar(chan, ctrl) == L2CAP_SAR_START; | ||
708 | } | ||
709 | |||
710 | static inline __u32 __get_sar_mask(struct l2cap_chan *chan) | ||
711 | { | ||
712 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
713 | return L2CAP_EXT_CTRL_SAR; | ||
714 | else | ||
715 | return L2CAP_CTRL_SAR; | ||
716 | } | ||
717 | |||
718 | static inline __u8 __get_ctrl_super(struct l2cap_chan *chan, __u32 ctrl) | ||
719 | { | ||
720 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
721 | return (ctrl & L2CAP_EXT_CTRL_SUPERVISE) >> | ||
722 | L2CAP_EXT_CTRL_SUPER_SHIFT; | ||
723 | else | ||
724 | return (ctrl & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT; | ||
725 | } | ||
726 | |||
727 | static inline __u32 __set_ctrl_super(struct l2cap_chan *chan, __u32 super) | ||
728 | { | ||
729 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
730 | return (super << L2CAP_EXT_CTRL_SUPER_SHIFT) & | ||
731 | L2CAP_EXT_CTRL_SUPERVISE; | ||
732 | else | ||
733 | return (super << L2CAP_CTRL_SUPER_SHIFT) & | ||
734 | L2CAP_CTRL_SUPERVISE; | ||
735 | } | ||
736 | |||
737 | static inline __u32 __set_ctrl_final(struct l2cap_chan *chan) | ||
738 | { | ||
739 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
740 | return L2CAP_EXT_CTRL_FINAL; | ||
741 | else | ||
742 | return L2CAP_CTRL_FINAL; | ||
743 | } | ||
744 | |||
745 | static inline bool __is_ctrl_final(struct l2cap_chan *chan, __u32 ctrl) | ||
746 | { | ||
747 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
748 | return ctrl & L2CAP_EXT_CTRL_FINAL; | ||
749 | else | ||
750 | return ctrl & L2CAP_CTRL_FINAL; | ||
751 | } | ||
752 | |||
753 | static inline __u32 __set_ctrl_poll(struct l2cap_chan *chan) | ||
754 | { | ||
755 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
756 | return L2CAP_EXT_CTRL_POLL; | ||
757 | else | ||
758 | return L2CAP_CTRL_POLL; | ||
759 | } | ||
760 | |||
761 | static inline bool __is_ctrl_poll(struct l2cap_chan *chan, __u32 ctrl) | ||
762 | { | ||
763 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
764 | return ctrl & L2CAP_EXT_CTRL_POLL; | ||
765 | else | ||
766 | return ctrl & L2CAP_CTRL_POLL; | ||
767 | } | ||
768 | |||
769 | static inline __u32 __get_control(struct l2cap_chan *chan, void *p) | ||
770 | { | ||
771 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
772 | return get_unaligned_le32(p); | ||
773 | else | ||
774 | return get_unaligned_le16(p); | ||
775 | } | ||
776 | |||
777 | static inline void __put_control(struct l2cap_chan *chan, __u32 control, | ||
778 | void *p) | ||
779 | { | ||
780 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
781 | return put_unaligned_le32(control, p); | ||
782 | else | ||
783 | return put_unaligned_le16(control, p); | ||
784 | } | ||
785 | |||
786 | static inline __u8 __ctrl_size(struct l2cap_chan *chan) | ||
787 | { | ||
788 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
789 | return L2CAP_EXT_HDR_SIZE - L2CAP_HDR_SIZE; | ||
790 | else | ||
791 | return L2CAP_ENH_HDR_SIZE - L2CAP_HDR_SIZE; | ||
792 | } | ||
491 | 793 | ||
492 | extern int disable_ertm; | 794 | extern int disable_ertm; |
795 | extern int enable_hs; | ||
493 | 796 | ||
494 | int l2cap_init_sockets(void); | 797 | int l2cap_init_sockets(void); |
495 | void l2cap_cleanup_sockets(void); | 798 | void l2cap_cleanup_sockets(void); |
@@ -504,7 +807,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk); | |||
504 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); | 807 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); |
505 | void l2cap_chan_destroy(struct l2cap_chan *chan); | 808 | void l2cap_chan_destroy(struct l2cap_chan *chan); |
506 | int l2cap_chan_connect(struct l2cap_chan *chan); | 809 | int l2cap_chan_connect(struct l2cap_chan *chan); |
507 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | 810 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
811 | u32 priority); | ||
508 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); | 812 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); |
509 | 813 | ||
510 | #endif /* __L2CAP_H */ | 814 | #endif /* __L2CAP_H */ |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index d66da0f94f95..3e320c9cae8f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -69,6 +69,10 @@ struct mgmt_mode { | |||
69 | #define MGMT_OP_SET_POWERED 0x0005 | 69 | #define MGMT_OP_SET_POWERED 0x0005 |
70 | 70 | ||
71 | #define MGMT_OP_SET_DISCOVERABLE 0x0006 | 71 | #define MGMT_OP_SET_DISCOVERABLE 0x0006 |
72 | struct mgmt_cp_set_discoverable { | ||
73 | __u8 val; | ||
74 | __u16 timeout; | ||
75 | } __packed; | ||
72 | 76 | ||
73 | #define MGMT_OP_SET_CONNECTABLE 0x0007 | 77 | #define MGMT_OP_SET_CONNECTABLE 0x0007 |
74 | 78 | ||
@@ -96,24 +100,22 @@ struct mgmt_cp_set_service_cache { | |||
96 | __u8 enable; | 100 | __u8 enable; |
97 | } __packed; | 101 | } __packed; |
98 | 102 | ||
99 | struct mgmt_key_info { | 103 | struct mgmt_link_key_info { |
100 | bdaddr_t bdaddr; | 104 | bdaddr_t bdaddr; |
101 | u8 type; | 105 | u8 type; |
102 | u8 val[16]; | 106 | u8 val[16]; |
103 | u8 pin_len; | 107 | u8 pin_len; |
104 | u8 dlen; | ||
105 | u8 data[0]; | ||
106 | } __packed; | 108 | } __packed; |
107 | 109 | ||
108 | #define MGMT_OP_LOAD_KEYS 0x000D | 110 | #define MGMT_OP_LOAD_LINK_KEYS 0x000D |
109 | struct mgmt_cp_load_keys { | 111 | struct mgmt_cp_load_link_keys { |
110 | __u8 debug_keys; | 112 | __u8 debug_keys; |
111 | __le16 key_count; | 113 | __le16 key_count; |
112 | struct mgmt_key_info keys[0]; | 114 | struct mgmt_link_key_info keys[0]; |
113 | } __packed; | 115 | } __packed; |
114 | 116 | ||
115 | #define MGMT_OP_REMOVE_KEY 0x000E | 117 | #define MGMT_OP_REMOVE_KEYS 0x000E |
116 | struct mgmt_cp_remove_key { | 118 | struct mgmt_cp_remove_keys { |
117 | bdaddr_t bdaddr; | 119 | bdaddr_t bdaddr; |
118 | __u8 disconnect; | 120 | __u8 disconnect; |
119 | } __packed; | 121 | } __packed; |
@@ -126,10 +128,20 @@ struct mgmt_rp_disconnect { | |||
126 | bdaddr_t bdaddr; | 128 | bdaddr_t bdaddr; |
127 | } __packed; | 129 | } __packed; |
128 | 130 | ||
131 | #define MGMT_ADDR_BREDR 0x00 | ||
132 | #define MGMT_ADDR_LE 0x01 | ||
133 | #define MGMT_ADDR_BREDR_LE 0x02 | ||
134 | #define MGMT_ADDR_INVALID 0xff | ||
135 | |||
136 | struct mgmt_addr_info { | ||
137 | bdaddr_t bdaddr; | ||
138 | __u8 type; | ||
139 | } __packed; | ||
140 | |||
129 | #define MGMT_OP_GET_CONNECTIONS 0x0010 | 141 | #define MGMT_OP_GET_CONNECTIONS 0x0010 |
130 | struct mgmt_rp_get_connections { | 142 | struct mgmt_rp_get_connections { |
131 | __le16 conn_count; | 143 | __le16 conn_count; |
132 | bdaddr_t conn[0]; | 144 | struct mgmt_addr_info addr[0]; |
133 | } __packed; | 145 | } __packed; |
134 | 146 | ||
135 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 | 147 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 |
@@ -245,26 +257,19 @@ struct mgmt_ev_controller_error { | |||
245 | 257 | ||
246 | #define MGMT_EV_PAIRABLE 0x0009 | 258 | #define MGMT_EV_PAIRABLE 0x0009 |
247 | 259 | ||
248 | #define MGMT_EV_NEW_KEY 0x000A | 260 | #define MGMT_EV_NEW_LINK_KEY 0x000A |
249 | struct mgmt_ev_new_key { | 261 | struct mgmt_ev_new_link_key { |
250 | __u8 store_hint; | 262 | __u8 store_hint; |
251 | struct mgmt_key_info key; | 263 | struct mgmt_link_key_info key; |
252 | } __packed; | 264 | } __packed; |
253 | 265 | ||
254 | #define MGMT_EV_CONNECTED 0x000B | 266 | #define MGMT_EV_CONNECTED 0x000B |
255 | struct mgmt_ev_connected { | ||
256 | bdaddr_t bdaddr; | ||
257 | __u8 link_type; | ||
258 | } __packed; | ||
259 | 267 | ||
260 | #define MGMT_EV_DISCONNECTED 0x000C | 268 | #define MGMT_EV_DISCONNECTED 0x000C |
261 | struct mgmt_ev_disconnected { | ||
262 | bdaddr_t bdaddr; | ||
263 | } __packed; | ||
264 | 269 | ||
265 | #define MGMT_EV_CONNECT_FAILED 0x000D | 270 | #define MGMT_EV_CONNECT_FAILED 0x000D |
266 | struct mgmt_ev_connect_failed { | 271 | struct mgmt_ev_connect_failed { |
267 | bdaddr_t bdaddr; | 272 | struct mgmt_addr_info addr; |
268 | __u8 status; | 273 | __u8 status; |
269 | } __packed; | 274 | } __packed; |
270 | 275 | ||
@@ -294,7 +299,7 @@ struct mgmt_ev_local_name_changed { | |||
294 | 299 | ||
295 | #define MGMT_EV_DEVICE_FOUND 0x0012 | 300 | #define MGMT_EV_DEVICE_FOUND 0x0012 |
296 | struct mgmt_ev_device_found { | 301 | struct mgmt_ev_device_found { |
297 | bdaddr_t bdaddr; | 302 | struct mgmt_addr_info addr; |
298 | __u8 dev_class[3]; | 303 | __u8 dev_class[3]; |
299 | __s8 rssi; | 304 | __s8 rssi; |
300 | __u8 eir[HCI_MAX_EIR_LENGTH]; | 305 | __u8 eir[HCI_MAX_EIR_LENGTH]; |