diff options
| -rw-r--r-- | include/net/bluetooth/hci.h | 70 | ||||
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 54 | ||||
| -rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
| -rw-r--r-- | net/bluetooth/hci_conn.c | 100 | ||||
| -rw-r--r-- | net/bluetooth/hci_core.c | 34 | ||||
| -rw-r--r-- | net/bluetooth/hci_event.c | 192 | ||||
| -rw-r--r-- | net/bluetooth/hci_sysfs.c | 88 |
7 files changed, 454 insertions, 86 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 99c53f6b8252..b2bdb1aa0429 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
| @@ -101,9 +101,10 @@ enum { | |||
| 101 | #define HCIINQUIRY _IOR('H', 240, int) | 101 | #define HCIINQUIRY _IOR('H', 240, int) |
| 102 | 102 | ||
| 103 | /* HCI timeouts */ | 103 | /* HCI timeouts */ |
| 104 | #define HCI_CONN_TIMEOUT (HZ * 40) | 104 | #define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ |
| 105 | #define HCI_DISCONN_TIMEOUT (HZ * 2) | 105 | #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ |
| 106 | #define HCI_CONN_IDLE_TIMEOUT (HZ * 60) | 106 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ |
| 107 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ | ||
| 107 | 108 | ||
| 108 | /* HCI Packet types */ | 109 | /* HCI Packet types */ |
| 109 | #define HCI_COMMAND_PKT 0x01 | 110 | #define HCI_COMMAND_PKT 0x01 |
| @@ -145,7 +146,7 @@ enum { | |||
| 145 | #define LMP_TACCURACY 0x10 | 146 | #define LMP_TACCURACY 0x10 |
| 146 | #define LMP_RSWITCH 0x20 | 147 | #define LMP_RSWITCH 0x20 |
| 147 | #define LMP_HOLD 0x40 | 148 | #define LMP_HOLD 0x40 |
| 148 | #define LMP_SNIF 0x80 | 149 | #define LMP_SNIFF 0x80 |
| 149 | 150 | ||
| 150 | #define LMP_PARK 0x01 | 151 | #define LMP_PARK 0x01 |
| 151 | #define LMP_RSSI 0x02 | 152 | #define LMP_RSSI 0x02 |
| @@ -160,13 +161,21 @@ enum { | |||
| 160 | #define LMP_PSCHEME 0x02 | 161 | #define LMP_PSCHEME 0x02 |
| 161 | #define LMP_PCONTROL 0x04 | 162 | #define LMP_PCONTROL 0x04 |
| 162 | 163 | ||
| 164 | #define LMP_SNIFF_SUBR 0x02 | ||
| 165 | |||
| 166 | /* Connection modes */ | ||
| 167 | #define HCI_CM_ACTIVE 0x0000 | ||
| 168 | #define HCI_CM_HOLD 0x0001 | ||
| 169 | #define HCI_CM_SNIFF 0x0002 | ||
| 170 | #define HCI_CM_PARK 0x0003 | ||
| 171 | |||
| 163 | /* Link policies */ | 172 | /* Link policies */ |
| 164 | #define HCI_LP_RSWITCH 0x0001 | 173 | #define HCI_LP_RSWITCH 0x0001 |
| 165 | #define HCI_LP_HOLD 0x0002 | 174 | #define HCI_LP_HOLD 0x0002 |
| 166 | #define HCI_LP_SNIFF 0x0004 | 175 | #define HCI_LP_SNIFF 0x0004 |
| 167 | #define HCI_LP_PARK 0x0008 | 176 | #define HCI_LP_PARK 0x0008 |
| 168 | 177 | ||
| 169 | /* Link mode */ | 178 | /* Link modes */ |
| 170 | #define HCI_LM_ACCEPT 0x8000 | 179 | #define HCI_LM_ACCEPT 0x8000 |
| 171 | #define HCI_LM_MASTER 0x0001 | 180 | #define HCI_LM_MASTER 0x0001 |
| 172 | #define HCI_LM_AUTH 0x0002 | 181 | #define HCI_LM_AUTH 0x0002 |
| @@ -192,7 +201,7 @@ struct hci_rp_read_loc_version { | |||
| 192 | } __attribute__ ((packed)); | 201 | } __attribute__ ((packed)); |
| 193 | 202 | ||
| 194 | #define OCF_READ_LOCAL_FEATURES 0x0003 | 203 | #define OCF_READ_LOCAL_FEATURES 0x0003 |
| 195 | struct hci_rp_read_loc_features { | 204 | struct hci_rp_read_local_features { |
| 196 | __u8 status; | 205 | __u8 status; |
| 197 | __u8 features[8]; | 206 | __u8 features[8]; |
| 198 | } __attribute__ ((packed)); | 207 | } __attribute__ ((packed)); |
| @@ -376,17 +385,32 @@ struct hci_cp_change_conn_link_key { | |||
| 376 | } __attribute__ ((packed)); | 385 | } __attribute__ ((packed)); |
| 377 | 386 | ||
| 378 | #define OCF_READ_REMOTE_FEATURES 0x001B | 387 | #define OCF_READ_REMOTE_FEATURES 0x001B |
| 379 | struct hci_cp_read_rmt_features { | 388 | struct hci_cp_read_remote_features { |
| 380 | __le16 handle; | 389 | __le16 handle; |
| 381 | } __attribute__ ((packed)); | 390 | } __attribute__ ((packed)); |
| 382 | 391 | ||
| 383 | #define OCF_READ_REMOTE_VERSION 0x001D | 392 | #define OCF_READ_REMOTE_VERSION 0x001D |
| 384 | struct hci_cp_read_rmt_version { | 393 | struct hci_cp_read_remote_version { |
| 385 | __le16 handle; | 394 | __le16 handle; |
| 386 | } __attribute__ ((packed)); | 395 | } __attribute__ ((packed)); |
| 387 | 396 | ||
| 388 | /* Link Policy */ | 397 | /* Link Policy */ |
| 389 | #define OGF_LINK_POLICY 0x02 | 398 | #define OGF_LINK_POLICY 0x02 |
| 399 | |||
| 400 | #define OCF_SNIFF_MODE 0x0003 | ||
| 401 | struct hci_cp_sniff_mode { | ||
| 402 | __le16 handle; | ||
| 403 | __le16 max_interval; | ||
| 404 | __le16 min_interval; | ||
| 405 | __le16 attempt; | ||
| 406 | __le16 timeout; | ||
| 407 | } __attribute__ ((packed)); | ||
| 408 | |||
| 409 | #define OCF_EXIT_SNIFF_MODE 0x0004 | ||
| 410 | struct hci_cp_exit_sniff_mode { | ||
| 411 | __le16 handle; | ||
| 412 | } __attribute__ ((packed)); | ||
| 413 | |||
| 390 | #define OCF_ROLE_DISCOVERY 0x0009 | 414 | #define OCF_ROLE_DISCOVERY 0x0009 |
| 391 | struct hci_cp_role_discovery { | 415 | struct hci_cp_role_discovery { |
| 392 | __le16 handle; | 416 | __le16 handle; |
| @@ -407,7 +431,7 @@ struct hci_rp_read_link_policy { | |||
| 407 | __le16 policy; | 431 | __le16 policy; |
| 408 | } __attribute__ ((packed)); | 432 | } __attribute__ ((packed)); |
| 409 | 433 | ||
| 410 | #define OCF_SWITCH_ROLE 0x000B | 434 | #define OCF_SWITCH_ROLE 0x000B |
| 411 | struct hci_cp_switch_role { | 435 | struct hci_cp_switch_role { |
| 412 | bdaddr_t bdaddr; | 436 | bdaddr_t bdaddr; |
| 413 | __u8 role; | 437 | __u8 role; |
| @@ -423,6 +447,14 @@ struct hci_rp_write_link_policy { | |||
| 423 | __le16 handle; | 447 | __le16 handle; |
| 424 | } __attribute__ ((packed)); | 448 | } __attribute__ ((packed)); |
| 425 | 449 | ||
| 450 | #define OCF_SNIFF_SUBRATE 0x0011 | ||
| 451 | struct hci_cp_sniff_subrate { | ||
| 452 | __le16 handle; | ||
| 453 | __le16 max_latency; | ||
| 454 | __le16 min_remote_timeout; | ||
| 455 | __le16 min_local_timeout; | ||
| 456 | } __attribute__ ((packed)); | ||
| 457 | |||
| 426 | /* Status params */ | 458 | /* Status params */ |
| 427 | #define OGF_STATUS_PARAM 0x05 | 459 | #define OGF_STATUS_PARAM 0x05 |
| 428 | 460 | ||
| @@ -582,15 +614,15 @@ struct hci_ev_link_key_notify { | |||
| 582 | __u8 key_type; | 614 | __u8 key_type; |
| 583 | } __attribute__ ((packed)); | 615 | } __attribute__ ((packed)); |
| 584 | 616 | ||
| 585 | #define HCI_EV_RMT_FEATURES 0x0B | 617 | #define HCI_EV_REMOTE_FEATURES 0x0B |
| 586 | struct hci_ev_rmt_features { | 618 | struct hci_ev_remote_features { |
| 587 | __u8 status; | 619 | __u8 status; |
| 588 | __le16 handle; | 620 | __le16 handle; |
| 589 | __u8 features[8]; | 621 | __u8 features[8]; |
| 590 | } __attribute__ ((packed)); | 622 | } __attribute__ ((packed)); |
| 591 | 623 | ||
| 592 | #define HCI_EV_RMT_VERSION 0x0C | 624 | #define HCI_EV_REMOTE_VERSION 0x0C |
| 593 | struct hci_ev_rmt_version { | 625 | struct hci_ev_remote_version { |
| 594 | __u8 status; | 626 | __u8 status; |
| 595 | __le16 handle; | 627 | __le16 handle; |
| 596 | __u8 lmp_ver; | 628 | __u8 lmp_ver; |
| @@ -611,6 +643,16 @@ struct hci_ev_pscan_rep_mode { | |||
| 611 | __u8 pscan_rep_mode; | 643 | __u8 pscan_rep_mode; |
| 612 | } __attribute__ ((packed)); | 644 | } __attribute__ ((packed)); |
| 613 | 645 | ||
| 646 | #define HCI_EV_SNIFF_SUBRATE 0x2E | ||
| 647 | struct hci_ev_sniff_subrate { | ||
| 648 | __u8 status; | ||
| 649 | __le16 handle; | ||
| 650 | __le16 max_tx_latency; | ||
| 651 | __le16 max_rx_latency; | ||
| 652 | __le16 max_remote_timeout; | ||
| 653 | __le16 max_local_timeout; | ||
| 654 | } __attribute__ ((packed)); | ||
| 655 | |||
| 614 | /* Internal events generated by Bluetooth stack */ | 656 | /* Internal events generated by Bluetooth stack */ |
| 615 | #define HCI_EV_STACK_INTERNAL 0xFD | 657 | #define HCI_EV_STACK_INTERNAL 0xFD |
| 616 | struct hci_ev_stack_internal { | 658 | struct hci_ev_stack_internal { |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index bb9f81dc8723..f6852707bd64 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
| @@ -31,10 +31,7 @@ | |||
| 31 | #define HCI_PROTO_L2CAP 0 | 31 | #define HCI_PROTO_L2CAP 0 |
| 32 | #define HCI_PROTO_SCO 1 | 32 | #define HCI_PROTO_SCO 1 |
| 33 | 33 | ||
| 34 | #define HCI_INIT_TIMEOUT (HZ * 10) | ||
| 35 | |||
| 36 | /* HCI Core structures */ | 34 | /* HCI Core structures */ |
| 37 | |||
| 38 | struct inquiry_data { | 35 | struct inquiry_data { |
| 39 | bdaddr_t bdaddr; | 36 | bdaddr_t bdaddr; |
| 40 | __u8 pscan_rep_mode; | 37 | __u8 pscan_rep_mode; |
| @@ -81,6 +78,10 @@ struct hci_dev { | |||
| 81 | __u16 link_policy; | 78 | __u16 link_policy; |
| 82 | __u16 link_mode; | 79 | __u16 link_mode; |
| 83 | 80 | ||
| 81 | __u32 idle_timeout; | ||
| 82 | __u16 sniff_min_interval; | ||
| 83 | __u16 sniff_max_interval; | ||
| 84 | |||
| 84 | unsigned long quirks; | 85 | unsigned long quirks; |
| 85 | 86 | ||
| 86 | atomic_t cmd_cnt; | 87 | atomic_t cmd_cnt; |
| @@ -145,18 +146,24 @@ struct hci_conn { | |||
| 145 | bdaddr_t dst; | 146 | bdaddr_t dst; |
| 146 | __u16 handle; | 147 | __u16 handle; |
| 147 | __u16 state; | 148 | __u16 state; |
| 149 | __u8 mode; | ||
| 148 | __u8 type; | 150 | __u8 type; |
| 149 | __u8 out; | 151 | __u8 out; |
| 150 | __u8 dev_class[3]; | 152 | __u8 dev_class[3]; |
| 153 | __u8 features[8]; | ||
| 154 | __u16 interval; | ||
| 155 | __u16 link_policy; | ||
| 151 | __u32 link_mode; | 156 | __u32 link_mode; |
| 157 | __u8 power_save; | ||
| 152 | unsigned long pend; | 158 | unsigned long pend; |
| 153 | 159 | ||
| 154 | unsigned int sent; | 160 | unsigned int sent; |
| 155 | 161 | ||
| 156 | struct sk_buff_head data_q; | 162 | struct sk_buff_head data_q; |
| 157 | 163 | ||
| 158 | struct timer_list timer; | 164 | struct timer_list disc_timer; |
| 159 | 165 | struct timer_list idle_timer; | |
| 166 | |||
| 160 | struct hci_dev *hdev; | 167 | struct hci_dev *hdev; |
| 161 | void *l2cap_data; | 168 | void *l2cap_data; |
| 162 | void *sco_data; | 169 | void *sco_data; |
| @@ -211,7 +218,8 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); | |||
| 211 | enum { | 218 | enum { |
| 212 | HCI_CONN_AUTH_PEND, | 219 | HCI_CONN_AUTH_PEND, |
| 213 | HCI_CONN_ENCRYPT_PEND, | 220 | HCI_CONN_ENCRYPT_PEND, |
| 214 | HCI_CONN_RSWITCH_PEND | 221 | HCI_CONN_RSWITCH_PEND, |
| 222 | HCI_CONN_MODE_CHANGE_PEND, | ||
| 215 | }; | 223 | }; |
| 216 | 224 | ||
| 217 | static inline void hci_conn_hash_init(struct hci_dev *hdev) | 225 | static inline void hci_conn_hash_init(struct hci_dev *hdev) |
| @@ -286,31 +294,27 @@ int hci_conn_encrypt(struct hci_conn *conn); | |||
| 286 | int hci_conn_change_link_key(struct hci_conn *conn); | 294 | int hci_conn_change_link_key(struct hci_conn *conn); |
| 287 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); | 295 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); |
| 288 | 296 | ||
| 289 | static inline void hci_conn_set_timer(struct hci_conn *conn, unsigned long timeout) | 297 | void hci_conn_enter_active_mode(struct hci_conn *conn); |
| 290 | { | 298 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); |
| 291 | mod_timer(&conn->timer, jiffies + timeout); | ||
| 292 | } | ||
| 293 | |||
| 294 | static inline void hci_conn_del_timer(struct hci_conn *conn) | ||
| 295 | { | ||
| 296 | del_timer(&conn->timer); | ||
| 297 | } | ||
| 298 | 299 | ||
| 299 | static inline void hci_conn_hold(struct hci_conn *conn) | 300 | static inline void hci_conn_hold(struct hci_conn *conn) |
| 300 | { | 301 | { |
| 301 | atomic_inc(&conn->refcnt); | 302 | atomic_inc(&conn->refcnt); |
| 302 | hci_conn_del_timer(conn); | 303 | del_timer(&conn->disc_timer); |
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | static inline void hci_conn_put(struct hci_conn *conn) | 306 | static inline void hci_conn_put(struct hci_conn *conn) |
| 306 | { | 307 | { |
| 307 | if (atomic_dec_and_test(&conn->refcnt)) { | 308 | if (atomic_dec_and_test(&conn->refcnt)) { |
| 309 | unsigned long timeo; | ||
| 308 | if (conn->type == ACL_LINK) { | 310 | if (conn->type == ACL_LINK) { |
| 309 | unsigned long timeo = (conn->out) ? | 311 | timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); |
| 310 | HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2; | 312 | if (!conn->out) |
| 311 | hci_conn_set_timer(conn, timeo); | 313 | timeo *= 2; |
| 314 | del_timer(&conn->idle_timer); | ||
| 312 | } else | 315 | } else |
| 313 | hci_conn_set_timer(conn, HZ / 100); | 316 | timeo = msecs_to_jiffies(10); |
| 317 | mod_timer(&conn->disc_timer, jiffies + timeo); | ||
| 314 | } | 318 | } |
| 315 | } | 319 | } |
| 316 | 320 | ||
| @@ -411,8 +415,10 @@ void hci_unregister_sysfs(struct hci_dev *hdev); | |||
| 411 | #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->class_dev.dev = (pdev)) | 415 | #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->class_dev.dev = (pdev)) |
| 412 | 416 | ||
| 413 | /* ----- LMP capabilities ----- */ | 417 | /* ----- LMP capabilities ----- */ |
| 414 | #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH) | 418 | #define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) |
| 415 | #define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT) | 419 | #define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) |
| 420 | #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) | ||
| 421 | #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) | ||
| 416 | 422 | ||
| 417 | /* ----- HCI protocols ----- */ | 423 | /* ----- HCI protocols ----- */ |
| 418 | struct hci_proto { | 424 | struct hci_proto { |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 51f867062e1d..729461fcfe99 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | #define BT_DBG(D...) | 48 | #define BT_DBG(D...) |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | #define VERSION "2.8" | 51 | #define VERSION "2.9" |
| 52 | 52 | ||
| 53 | /* Bluetooth sockets */ | 53 | /* Bluetooth sockets */ |
| 54 | #define BT_MAX_PROTO 8 | 54 | #define BT_MAX_PROTO 8 |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5c0c2b1ef34a..420ed4d7e57e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -115,8 +115,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle) | |||
| 115 | 115 | ||
| 116 | static void hci_conn_timeout(unsigned long arg) | 116 | static void hci_conn_timeout(unsigned long arg) |
| 117 | { | 117 | { |
| 118 | struct hci_conn *conn = (void *)arg; | 118 | struct hci_conn *conn = (void *) arg; |
| 119 | struct hci_dev *hdev = conn->hdev; | 119 | struct hci_dev *hdev = conn->hdev; |
| 120 | 120 | ||
| 121 | BT_DBG("conn %p state %d", conn, conn->state); | 121 | BT_DBG("conn %p state %d", conn, conn->state); |
| 122 | 122 | ||
| @@ -132,11 +132,13 @@ static void hci_conn_timeout(unsigned long arg) | |||
| 132 | return; | 132 | return; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | static void hci_conn_init_timer(struct hci_conn *conn) | 135 | static void hci_conn_idle(unsigned long arg) |
| 136 | { | 136 | { |
| 137 | init_timer(&conn->timer); | 137 | struct hci_conn *conn = (void *) arg; |
| 138 | conn->timer.function = hci_conn_timeout; | 138 | |
| 139 | conn->timer.data = (unsigned long)conn; | 139 | BT_DBG("conn %p mode %d", conn, conn->mode); |
| 140 | |||
| 141 | hci_conn_enter_sniff_mode(conn); | ||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 144 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) |
| @@ -145,17 +147,27 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
| 145 | 147 | ||
| 146 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 148 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
| 147 | 149 | ||
| 148 | if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC))) | 150 | conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC); |
| 151 | if (!conn) | ||
| 149 | return NULL; | 152 | return NULL; |
| 150 | memset(conn, 0, sizeof(struct hci_conn)); | ||
| 151 | 153 | ||
| 152 | bacpy(&conn->dst, dst); | 154 | bacpy(&conn->dst, dst); |
| 153 | conn->type = type; | ||
| 154 | conn->hdev = hdev; | 155 | conn->hdev = hdev; |
| 156 | conn->type = type; | ||
| 157 | conn->mode = HCI_CM_ACTIVE; | ||
| 155 | conn->state = BT_OPEN; | 158 | conn->state = BT_OPEN; |
| 156 | 159 | ||
| 160 | conn->power_save = 1; | ||
| 161 | |||
| 157 | skb_queue_head_init(&conn->data_q); | 162 | skb_queue_head_init(&conn->data_q); |
| 158 | hci_conn_init_timer(conn); | 163 | |
| 164 | init_timer(&conn->disc_timer); | ||
| 165 | conn->disc_timer.function = hci_conn_timeout; | ||
| 166 | conn->disc_timer.data = (unsigned long) conn; | ||
| 167 | |||
| 168 | init_timer(&conn->idle_timer); | ||
| 169 | conn->idle_timer.function = hci_conn_idle; | ||
| 170 | conn->idle_timer.data = (unsigned long) conn; | ||
| 159 | 171 | ||
| 160 | atomic_set(&conn->refcnt, 0); | 172 | atomic_set(&conn->refcnt, 0); |
| 161 | 173 | ||
| @@ -178,7 +190,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
| 178 | 190 | ||
| 179 | BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle); | 191 | BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle); |
| 180 | 192 | ||
| 181 | hci_conn_del_timer(conn); | 193 | del_timer(&conn->idle_timer); |
| 194 | |||
| 195 | del_timer(&conn->disc_timer); | ||
| 182 | 196 | ||
| 183 | if (conn->type == SCO_LINK) { | 197 | if (conn->type == SCO_LINK) { |
| 184 | struct hci_conn *acl = conn->link; | 198 | struct hci_conn *acl = conn->link; |
| @@ -364,6 +378,70 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) | |||
| 364 | } | 378 | } |
| 365 | EXPORT_SYMBOL(hci_conn_switch_role); | 379 | EXPORT_SYMBOL(hci_conn_switch_role); |
| 366 | 380 | ||
| 381 | /* Enter active mode */ | ||
| 382 | void hci_conn_enter_active_mode(struct hci_conn *conn) | ||
| 383 | { | ||
| 384 | struct hci_dev *hdev = conn->hdev; | ||
| 385 | |||
| 386 | BT_DBG("conn %p mode %d", conn, conn->mode); | ||
| 387 | |||
| 388 | if (test_bit(HCI_RAW, &hdev->flags)) | ||
| 389 | return; | ||
| 390 | |||
| 391 | if (conn->mode != HCI_CM_SNIFF || !conn->power_save) | ||
| 392 | goto timer; | ||
| 393 | |||
| 394 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
| 395 | struct hci_cp_exit_sniff_mode cp; | ||
| 396 | cp.handle = __cpu_to_le16(conn->handle); | ||
| 397 | hci_send_cmd(hdev, OGF_LINK_POLICY, | ||
| 398 | OCF_EXIT_SNIFF_MODE, sizeof(cp), &cp); | ||
| 399 | } | ||
| 400 | |||
| 401 | timer: | ||
| 402 | if (hdev->idle_timeout > 0) | ||
| 403 | mod_timer(&conn->idle_timer, | ||
| 404 | jiffies + msecs_to_jiffies(hdev->idle_timeout)); | ||
| 405 | } | ||
| 406 | |||
| 407 | /* Enter sniff mode */ | ||
| 408 | void hci_conn_enter_sniff_mode(struct hci_conn *conn) | ||
| 409 | { | ||
| 410 | struct hci_dev *hdev = conn->hdev; | ||
| 411 | |||
| 412 | BT_DBG("conn %p mode %d", conn, conn->mode); | ||
| 413 | |||
| 414 | if (test_bit(HCI_RAW, &hdev->flags)) | ||
| 415 | return; | ||
| 416 | |||
| 417 | if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn)) | ||
| 418 | return; | ||
| 419 | |||
| 420 | if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF)) | ||
| 421 | return; | ||
| 422 | |||
| 423 | if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { | ||
| 424 | struct hci_cp_sniff_subrate cp; | ||
| 425 | cp.handle = __cpu_to_le16(conn->handle); | ||
| 426 | cp.max_latency = __constant_cpu_to_le16(0); | ||
| 427 | cp.min_remote_timeout = __constant_cpu_to_le16(0); | ||
| 428 | cp.min_local_timeout = __constant_cpu_to_le16(0); | ||
| 429 | hci_send_cmd(hdev, OGF_LINK_POLICY, | ||
| 430 | OCF_SNIFF_SUBRATE, sizeof(cp), &cp); | ||
| 431 | } | ||
| 432 | |||
| 433 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
| 434 | struct hci_cp_sniff_mode cp; | ||
| 435 | cp.handle = __cpu_to_le16(conn->handle); | ||
| 436 | cp.max_interval = __cpu_to_le16(hdev->sniff_max_interval); | ||
| 437 | cp.min_interval = __cpu_to_le16(hdev->sniff_min_interval); | ||
| 438 | cp.attempt = __constant_cpu_to_le16(4); | ||
| 439 | cp.timeout = __constant_cpu_to_le16(1); | ||
| 440 | hci_send_cmd(hdev, OGF_LINK_POLICY, | ||
| 441 | OCF_SNIFF_MODE, sizeof(cp), &cp); | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 367 | /* Drop all connection on the device */ | 445 | /* Drop all connection on the device */ |
| 368 | void hci_conn_hash_flush(struct hci_dev *hdev) | 446 | void hci_conn_hash_flush(struct hci_dev *hdev) |
| 369 | { | 447 | { |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f67240beb0dd..3f9f1565bf06 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -411,7 +411,7 @@ int hci_inquiry(void __user *arg) | |||
| 411 | } | 411 | } |
| 412 | hci_dev_unlock_bh(hdev); | 412 | hci_dev_unlock_bh(hdev); |
| 413 | 413 | ||
| 414 | timeo = ir.length * 2 * HZ; | 414 | timeo = ir.length * msecs_to_jiffies(2000); |
| 415 | if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0) | 415 | if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0) |
| 416 | goto done; | 416 | goto done; |
| 417 | 417 | ||
| @@ -479,7 +479,8 @@ int hci_dev_open(__u16 dev) | |||
| 479 | set_bit(HCI_INIT, &hdev->flags); | 479 | set_bit(HCI_INIT, &hdev->flags); |
| 480 | 480 | ||
| 481 | //__hci_request(hdev, hci_reset_req, 0, HZ); | 481 | //__hci_request(hdev, hci_reset_req, 0, HZ); |
| 482 | ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); | 482 | ret = __hci_request(hdev, hci_init_req, 0, |
| 483 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
| 483 | 484 | ||
| 484 | clear_bit(HCI_INIT, &hdev->flags); | 485 | clear_bit(HCI_INIT, &hdev->flags); |
| 485 | } | 486 | } |
| @@ -546,7 +547,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
| 546 | atomic_set(&hdev->cmd_cnt, 1); | 547 | atomic_set(&hdev->cmd_cnt, 1); |
| 547 | if (!test_bit(HCI_RAW, &hdev->flags)) { | 548 | if (!test_bit(HCI_RAW, &hdev->flags)) { |
| 548 | set_bit(HCI_INIT, &hdev->flags); | 549 | set_bit(HCI_INIT, &hdev->flags); |
| 549 | __hci_request(hdev, hci_reset_req, 0, HZ/4); | 550 | __hci_request(hdev, hci_reset_req, 0, |
| 551 | msecs_to_jiffies(250)); | ||
| 550 | clear_bit(HCI_INIT, &hdev->flags); | 552 | clear_bit(HCI_INIT, &hdev->flags); |
| 551 | } | 553 | } |
| 552 | 554 | ||
| @@ -619,7 +621,8 @@ int hci_dev_reset(__u16 dev) | |||
| 619 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; | 621 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; |
| 620 | 622 | ||
| 621 | if (!test_bit(HCI_RAW, &hdev->flags)) | 623 | if (!test_bit(HCI_RAW, &hdev->flags)) |
| 622 | ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); | 624 | ret = __hci_request(hdev, hci_reset_req, 0, |
| 625 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
| 623 | 626 | ||
| 624 | done: | 627 | done: |
| 625 | tasklet_enable(&hdev->tx_task); | 628 | tasklet_enable(&hdev->tx_task); |
| @@ -657,7 +660,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
| 657 | 660 | ||
| 658 | switch (cmd) { | 661 | switch (cmd) { |
| 659 | case HCISETAUTH: | 662 | case HCISETAUTH: |
| 660 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT); | 663 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, |
| 664 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
| 661 | break; | 665 | break; |
| 662 | 666 | ||
| 663 | case HCISETENCRYPT: | 667 | case HCISETENCRYPT: |
| @@ -668,18 +672,19 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
| 668 | 672 | ||
| 669 | if (!test_bit(HCI_AUTH, &hdev->flags)) { | 673 | if (!test_bit(HCI_AUTH, &hdev->flags)) { |
| 670 | /* Auth must be enabled first */ | 674 | /* Auth must be enabled first */ |
| 671 | err = hci_request(hdev, hci_auth_req, | 675 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, |
| 672 | dr.dev_opt, HCI_INIT_TIMEOUT); | 676 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
| 673 | if (err) | 677 | if (err) |
| 674 | break; | 678 | break; |
| 675 | } | 679 | } |
| 676 | 680 | ||
| 677 | err = hci_request(hdev, hci_encrypt_req, | 681 | err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, |
| 678 | dr.dev_opt, HCI_INIT_TIMEOUT); | 682 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
| 679 | break; | 683 | break; |
| 680 | 684 | ||
| 681 | case HCISETSCAN: | 685 | case HCISETSCAN: |
| 682 | err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT); | 686 | err = hci_request(hdev, hci_scan_req, dr.dev_opt, |
| 687 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
| 683 | break; | 688 | break; |
| 684 | 689 | ||
| 685 | case HCISETPTYPE: | 690 | case HCISETPTYPE: |
| @@ -848,6 +853,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
| 848 | hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); | 853 | hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); |
| 849 | hdev->link_mode = (HCI_LM_ACCEPT); | 854 | hdev->link_mode = (HCI_LM_ACCEPT); |
| 850 | 855 | ||
| 856 | hdev->idle_timeout = 0; | ||
| 857 | hdev->sniff_max_interval = 800; | ||
| 858 | hdev->sniff_min_interval = 80; | ||
| 859 | |||
| 851 | tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev); | 860 | tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev); |
| 852 | tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev); | 861 | tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev); |
| 853 | tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev); | 862 | tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev); |
| @@ -1220,6 +1229,9 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
| 1220 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { | 1229 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { |
| 1221 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 1230 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { |
| 1222 | BT_DBG("skb %p len %d", skb, skb->len); | 1231 | BT_DBG("skb %p len %d", skb, skb->len); |
| 1232 | |||
| 1233 | hci_conn_enter_active_mode(conn); | ||
| 1234 | |||
| 1223 | hci_send_frame(skb); | 1235 | hci_send_frame(skb); |
| 1224 | hdev->acl_last_tx = jiffies; | 1236 | hdev->acl_last_tx = jiffies; |
| 1225 | 1237 | ||
| @@ -1298,6 +1310,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1298 | if (conn) { | 1310 | if (conn) { |
| 1299 | register struct hci_proto *hp; | 1311 | register struct hci_proto *hp; |
| 1300 | 1312 | ||
| 1313 | hci_conn_enter_active_mode(conn); | ||
| 1314 | |||
| 1301 | /* Send to upper protocol */ | 1315 | /* Send to upper protocol */ |
| 1302 | if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) { | 1316 | if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) { |
| 1303 | hp->recv_acldata(conn, skb, flags); | 1317 | hp->recv_acldata(conn, skb, flags); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f41cf1a6c11a..3896dabab11d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -83,6 +83,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 83 | { | 83 | { |
| 84 | struct hci_conn *conn; | 84 | struct hci_conn *conn; |
| 85 | struct hci_rp_role_discovery *rd; | 85 | struct hci_rp_role_discovery *rd; |
| 86 | struct hci_rp_write_link_policy *lp; | ||
| 87 | void *sent; | ||
| 86 | 88 | ||
| 87 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 89 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 88 | 90 | ||
| @@ -106,6 +108,27 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 106 | hci_dev_unlock(hdev); | 108 | hci_dev_unlock(hdev); |
| 107 | break; | 109 | break; |
| 108 | 110 | ||
| 111 | case OCF_WRITE_LINK_POLICY: | ||
| 112 | sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY); | ||
| 113 | if (!sent) | ||
| 114 | break; | ||
| 115 | |||
| 116 | lp = (struct hci_rp_write_link_policy *) skb->data; | ||
| 117 | |||
| 118 | if (lp->status) | ||
| 119 | break; | ||
| 120 | |||
| 121 | hci_dev_lock(hdev); | ||
| 122 | |||
| 123 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle)); | ||
| 124 | if (conn) { | ||
| 125 | __le16 policy = get_unaligned((__le16 *) (sent + 2)); | ||
| 126 | conn->link_policy = __le16_to_cpu(policy); | ||
| 127 | } | ||
| 128 | |||
| 129 | hci_dev_unlock(hdev); | ||
| 130 | break; | ||
| 131 | |||
| 109 | default: | 132 | default: |
| 110 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", | 133 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", |
| 111 | hdev->name, ocf); | 134 | hdev->name, ocf); |
| @@ -274,7 +297,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
| 274 | /* Command Complete OGF INFO_PARAM */ | 297 | /* Command Complete OGF INFO_PARAM */ |
| 275 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) | 298 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) |
| 276 | { | 299 | { |
| 277 | struct hci_rp_read_loc_features *lf; | 300 | struct hci_rp_read_local_features *lf; |
| 278 | struct hci_rp_read_buffer_size *bs; | 301 | struct hci_rp_read_buffer_size *bs; |
| 279 | struct hci_rp_read_bd_addr *ba; | 302 | struct hci_rp_read_bd_addr *ba; |
| 280 | 303 | ||
| @@ -282,7 +305,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s | |||
| 282 | 305 | ||
| 283 | switch (ocf) { | 306 | switch (ocf) { |
| 284 | case OCF_READ_LOCAL_FEATURES: | 307 | case OCF_READ_LOCAL_FEATURES: |
| 285 | lf = (struct hci_rp_read_loc_features *) skb->data; | 308 | lf = (struct hci_rp_read_local_features *) skb->data; |
| 286 | 309 | ||
| 287 | if (lf->status) { | 310 | if (lf->status) { |
| 288 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); | 311 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); |
| @@ -447,8 +470,46 @@ static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status) | |||
| 447 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 470 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 448 | 471 | ||
| 449 | switch (ocf) { | 472 | switch (ocf) { |
| 473 | case OCF_SNIFF_MODE: | ||
| 474 | if (status) { | ||
| 475 | struct hci_conn *conn; | ||
| 476 | struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE); | ||
| 477 | |||
| 478 | if (!cp) | ||
| 479 | break; | ||
| 480 | |||
| 481 | hci_dev_lock(hdev); | ||
| 482 | |||
| 483 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 484 | if (conn) { | ||
| 485 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 486 | } | ||
| 487 | |||
| 488 | hci_dev_unlock(hdev); | ||
| 489 | } | ||
| 490 | break; | ||
| 491 | |||
| 492 | case OCF_EXIT_SNIFF_MODE: | ||
| 493 | if (status) { | ||
| 494 | struct hci_conn *conn; | ||
| 495 | struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE); | ||
| 496 | |||
| 497 | if (!cp) | ||
| 498 | break; | ||
| 499 | |||
| 500 | hci_dev_lock(hdev); | ||
| 501 | |||
| 502 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 503 | if (conn) { | ||
| 504 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 505 | } | ||
| 506 | |||
| 507 | hci_dev_unlock(hdev); | ||
| 508 | } | ||
| 509 | break; | ||
| 510 | |||
| 450 | default: | 511 | default: |
| 451 | BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf); | 512 | BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf); |
| 452 | break; | 513 | break; |
| 453 | } | 514 | } |
| 454 | } | 515 | } |
| @@ -630,14 +691,16 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 630 | else | 691 | else |
| 631 | cp.role = 0x01; /* Remain slave */ | 692 | cp.role = 0x01; /* Remain slave */ |
| 632 | 693 | ||
| 633 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | 694 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 695 | OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
| 634 | } else { | 696 | } else { |
| 635 | /* Connection rejected */ | 697 | /* Connection rejected */ |
| 636 | struct hci_cp_reject_conn_req cp; | 698 | struct hci_cp_reject_conn_req cp; |
| 637 | 699 | ||
| 638 | bacpy(&cp.bdaddr, &ev->bdaddr); | 700 | bacpy(&cp.bdaddr, &ev->bdaddr); |
| 639 | cp.reason = 0x0f; | 701 | cp.reason = 0x0f; |
| 640 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | 702 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 703 | OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | ||
| 641 | } | 704 | } |
| 642 | } | 705 | } |
| 643 | 706 | ||
| @@ -645,7 +708,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 645 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 708 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 646 | { | 709 | { |
| 647 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; | 710 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; |
| 648 | struct hci_conn *conn = NULL; | 711 | struct hci_conn *conn; |
| 649 | 712 | ||
| 650 | BT_DBG("%s", hdev->name); | 713 | BT_DBG("%s", hdev->name); |
| 651 | 714 | ||
| @@ -667,12 +730,21 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 667 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) | 730 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) |
| 668 | conn->link_mode |= HCI_LM_ENCRYPT; | 731 | conn->link_mode |= HCI_LM_ENCRYPT; |
| 669 | 732 | ||
| 733 | /* Get remote features */ | ||
| 734 | if (conn->type == ACL_LINK) { | ||
| 735 | struct hci_cp_read_remote_features cp; | ||
| 736 | cp.handle = ev->handle; | ||
| 737 | hci_send_cmd(hdev, OGF_LINK_CTL, | ||
| 738 | OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp); | ||
| 739 | } | ||
| 740 | |||
| 670 | /* Set link policy */ | 741 | /* Set link policy */ |
| 671 | if (conn->type == ACL_LINK && hdev->link_policy) { | 742 | if (conn->type == ACL_LINK && hdev->link_policy) { |
| 672 | struct hci_cp_write_link_policy cp; | 743 | struct hci_cp_write_link_policy cp; |
| 673 | cp.handle = ev->handle; | 744 | cp.handle = ev->handle; |
| 674 | cp.policy = __cpu_to_le16(hdev->link_policy); | 745 | cp.policy = __cpu_to_le16(hdev->link_policy); |
| 675 | hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | 746 | hci_send_cmd(hdev, OGF_LINK_POLICY, |
| 747 | OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | ||
| 676 | } | 748 | } |
| 677 | 749 | ||
| 678 | /* Set packet type for incoming connection */ | 750 | /* Set packet type for incoming connection */ |
| @@ -683,7 +755,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 683 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): | 755 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): |
| 684 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 756 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); |
| 685 | 757 | ||
| 686 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | 758 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 759 | OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | ||
| 687 | } | 760 | } |
| 688 | } else | 761 | } else |
| 689 | conn->state = BT_CLOSED; | 762 | conn->state = BT_CLOSED; |
| @@ -711,8 +784,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 711 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 784 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 712 | { | 785 | { |
| 713 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; | 786 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; |
| 714 | struct hci_conn *conn = NULL; | 787 | struct hci_conn *conn; |
| 715 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 716 | 788 | ||
| 717 | BT_DBG("%s status %d", hdev->name, ev->status); | 789 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 718 | 790 | ||
| @@ -721,7 +793,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
| 721 | 793 | ||
| 722 | hci_dev_lock(hdev); | 794 | hci_dev_lock(hdev); |
| 723 | 795 | ||
| 724 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 796 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 725 | if (conn) { | 797 | if (conn) { |
| 726 | conn->state = BT_CLOSED; | 798 | conn->state = BT_CLOSED; |
| 727 | hci_proto_disconn_ind(conn, ev->reason); | 799 | hci_proto_disconn_ind(conn, ev->reason); |
| @@ -778,7 +850,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 778 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 850 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 779 | { | 851 | { |
| 780 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; | 852 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; |
| 781 | struct hci_conn *conn = NULL; | 853 | struct hci_conn *conn; |
| 782 | 854 | ||
| 783 | BT_DBG("%s status %d", hdev->name, ev->status); | 855 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 784 | 856 | ||
| @@ -801,18 +873,43 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
| 801 | hci_dev_unlock(hdev); | 873 | hci_dev_unlock(hdev); |
| 802 | } | 874 | } |
| 803 | 875 | ||
| 876 | /* Mode Change */ | ||
| 877 | static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 878 | { | ||
| 879 | struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data; | ||
| 880 | struct hci_conn *conn; | ||
| 881 | |||
| 882 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 883 | |||
| 884 | hci_dev_lock(hdev); | ||
| 885 | |||
| 886 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 887 | if (conn) { | ||
| 888 | conn->mode = ev->mode; | ||
| 889 | conn->interval = __le16_to_cpu(ev->interval); | ||
| 890 | |||
| 891 | if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
| 892 | if (conn->mode == HCI_CM_ACTIVE) | ||
| 893 | conn->power_save = 1; | ||
| 894 | else | ||
| 895 | conn->power_save = 0; | ||
| 896 | } | ||
| 897 | } | ||
| 898 | |||
| 899 | hci_dev_unlock(hdev); | ||
| 900 | } | ||
| 901 | |||
| 804 | /* Authentication Complete */ | 902 | /* Authentication Complete */ |
| 805 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 903 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 806 | { | 904 | { |
| 807 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; | 905 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; |
| 808 | struct hci_conn *conn = NULL; | 906 | struct hci_conn *conn; |
| 809 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 810 | 907 | ||
| 811 | BT_DBG("%s status %d", hdev->name, ev->status); | 908 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 812 | 909 | ||
| 813 | hci_dev_lock(hdev); | 910 | hci_dev_lock(hdev); |
| 814 | 911 | ||
| 815 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 912 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 816 | if (conn) { | 913 | if (conn) { |
| 817 | if (!ev->status) | 914 | if (!ev->status) |
| 818 | conn->link_mode |= HCI_LM_AUTH; | 915 | conn->link_mode |= HCI_LM_AUTH; |
| @@ -827,8 +924,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 827 | cp.handle = __cpu_to_le16(conn->handle); | 924 | cp.handle = __cpu_to_le16(conn->handle); |
| 828 | cp.encrypt = 1; | 925 | cp.encrypt = 1; |
| 829 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | 926 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, |
| 830 | OCF_SET_CONN_ENCRYPT, | 927 | OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp); |
| 831 | sizeof(cp), &cp); | ||
| 832 | } else { | 928 | } else { |
| 833 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 929 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); |
| 834 | hci_encrypt_cfm(conn, ev->status, 0x00); | 930 | hci_encrypt_cfm(conn, ev->status, 0x00); |
| @@ -843,14 +939,13 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 843 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 939 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 844 | { | 940 | { |
| 845 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; | 941 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; |
| 846 | struct hci_conn *conn = NULL; | 942 | struct hci_conn *conn; |
| 847 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 848 | 943 | ||
| 849 | BT_DBG("%s status %d", hdev->name, ev->status); | 944 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 850 | 945 | ||
| 851 | hci_dev_lock(hdev); | 946 | hci_dev_lock(hdev); |
| 852 | 947 | ||
| 853 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 948 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 854 | if (conn) { | 949 | if (conn) { |
| 855 | if (!ev->status) { | 950 | if (!ev->status) { |
| 856 | if (ev->encrypt) | 951 | if (ev->encrypt) |
| @@ -871,14 +966,13 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 871 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 966 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 872 | { | 967 | { |
| 873 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; | 968 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; |
| 874 | struct hci_conn *conn = NULL; | 969 | struct hci_conn *conn; |
| 875 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 876 | 970 | ||
| 877 | BT_DBG("%s status %d", hdev->name, ev->status); | 971 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 878 | 972 | ||
| 879 | hci_dev_lock(hdev); | 973 | hci_dev_lock(hdev); |
| 880 | 974 | ||
| 881 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 975 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 882 | if (conn) { | 976 | if (conn) { |
| 883 | if (!ev->status) | 977 | if (!ev->status) |
| 884 | conn->link_mode |= HCI_LM_SECURE; | 978 | conn->link_mode |= HCI_LM_SECURE; |
| @@ -906,18 +1000,35 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
| 906 | { | 1000 | { |
| 907 | } | 1001 | } |
| 908 | 1002 | ||
| 1003 | /* Remote Features */ | ||
| 1004 | static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1005 | { | ||
| 1006 | struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data; | ||
| 1007 | struct hci_conn *conn; | ||
| 1008 | |||
| 1009 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1010 | |||
| 1011 | hci_dev_lock(hdev); | ||
| 1012 | |||
| 1013 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1014 | if (conn && !ev->status) { | ||
| 1015 | memcpy(conn->features, ev->features, sizeof(conn->features)); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | hci_dev_unlock(hdev); | ||
| 1019 | } | ||
| 1020 | |||
| 909 | /* Clock Offset */ | 1021 | /* Clock Offset */ |
| 910 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1022 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 911 | { | 1023 | { |
| 912 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; | 1024 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; |
| 913 | struct hci_conn *conn = NULL; | 1025 | struct hci_conn *conn; |
| 914 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 915 | 1026 | ||
| 916 | BT_DBG("%s status %d", hdev->name, ev->status); | 1027 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 917 | 1028 | ||
| 918 | hci_dev_lock(hdev); | 1029 | hci_dev_lock(hdev); |
| 919 | 1030 | ||
| 920 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 1031 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 921 | if (conn && !ev->status) { | 1032 | if (conn && !ev->status) { |
| 922 | struct inquiry_entry *ie; | 1033 | struct inquiry_entry *ie; |
| 923 | 1034 | ||
| @@ -948,6 +1059,23 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 948 | hci_dev_unlock(hdev); | 1059 | hci_dev_unlock(hdev); |
| 949 | } | 1060 | } |
| 950 | 1061 | ||
| 1062 | /* Sniff Subrate */ | ||
| 1063 | static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1064 | { | ||
| 1065 | struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data; | ||
| 1066 | struct hci_conn *conn; | ||
| 1067 | |||
| 1068 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1069 | |||
| 1070 | hci_dev_lock(hdev); | ||
| 1071 | |||
| 1072 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1073 | if (conn) { | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | hci_dev_unlock(hdev); | ||
| 1077 | } | ||
| 1078 | |||
| 951 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 1079 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
| 952 | { | 1080 | { |
| 953 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; | 1081 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; |
| @@ -996,6 +1124,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 996 | hci_role_change_evt(hdev, skb); | 1124 | hci_role_change_evt(hdev, skb); |
| 997 | break; | 1125 | break; |
| 998 | 1126 | ||
| 1127 | case HCI_EV_MODE_CHANGE: | ||
| 1128 | hci_mode_change_evt(hdev, skb); | ||
| 1129 | break; | ||
| 1130 | |||
| 999 | case HCI_EV_AUTH_COMPLETE: | 1131 | case HCI_EV_AUTH_COMPLETE: |
| 1000 | hci_auth_complete_evt(hdev, skb); | 1132 | hci_auth_complete_evt(hdev, skb); |
| 1001 | break; | 1133 | break; |
| @@ -1020,6 +1152,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1020 | hci_link_key_notify_evt(hdev, skb); | 1152 | hci_link_key_notify_evt(hdev, skb); |
| 1021 | break; | 1153 | break; |
| 1022 | 1154 | ||
| 1155 | case HCI_EV_REMOTE_FEATURES: | ||
| 1156 | hci_remote_features_evt(hdev, skb); | ||
| 1157 | break; | ||
| 1158 | |||
| 1023 | case HCI_EV_CLOCK_OFFSET: | 1159 | case HCI_EV_CLOCK_OFFSET: |
| 1024 | hci_clock_offset_evt(hdev, skb); | 1160 | hci_clock_offset_evt(hdev, skb); |
| 1025 | break; | 1161 | break; |
| @@ -1028,6 +1164,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1028 | hci_pscan_rep_mode_evt(hdev, skb); | 1164 | hci_pscan_rep_mode_evt(hdev, skb); |
| 1029 | break; | 1165 | break; |
| 1030 | 1166 | ||
| 1167 | case HCI_EV_SNIFF_SUBRATE: | ||
| 1168 | hci_sniff_subrate_evt(hdev, skb); | ||
| 1169 | break; | ||
| 1170 | |||
| 1031 | case HCI_EV_CMD_STATUS: | 1171 | case HCI_EV_CMD_STATUS: |
| 1032 | cs = (struct hci_ev_cmd_status *) skb->data; | 1172 | cs = (struct hci_ev_cmd_status *) skb->data; |
| 1033 | skb_pull(skb, sizeof(cs)); | 1173 | skb_pull(skb, sizeof(cs)); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 19b234c86f33..89918d2f1fdc 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
| @@ -61,18 +61,106 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf) | |||
| 61 | return n; | 61 | return n; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static ssize_t show_idle_timeout(struct class_device *cdev, char *buf) | ||
| 65 | { | ||
| 66 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 67 | return sprintf(buf, "%d\n", hdev->idle_timeout); | ||
| 68 | } | ||
| 69 | |||
| 70 | static ssize_t store_idle_timeout(struct class_device *cdev, const char *buf, size_t count) | ||
| 71 | { | ||
| 72 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 73 | char *ptr; | ||
| 74 | __u32 val; | ||
| 75 | |||
| 76 | val = simple_strtoul(buf, &ptr, 10); | ||
| 77 | if (ptr == buf) | ||
| 78 | return -EINVAL; | ||
| 79 | |||
| 80 | if (val != 0 && (val < 500 || val > 3600000)) | ||
| 81 | return -EINVAL; | ||
| 82 | |||
| 83 | hdev->idle_timeout = val; | ||
| 84 | |||
| 85 | return count; | ||
| 86 | } | ||
| 87 | |||
| 88 | static ssize_t show_sniff_max_interval(struct class_device *cdev, char *buf) | ||
| 89 | { | ||
| 90 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 91 | return sprintf(buf, "%d\n", hdev->sniff_max_interval); | ||
| 92 | } | ||
| 93 | |||
| 94 | static ssize_t store_sniff_max_interval(struct class_device *cdev, const char *buf, size_t count) | ||
| 95 | { | ||
| 96 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 97 | char *ptr; | ||
| 98 | __u16 val; | ||
| 99 | |||
| 100 | val = simple_strtoul(buf, &ptr, 10); | ||
| 101 | if (ptr == buf) | ||
| 102 | return -EINVAL; | ||
| 103 | |||
| 104 | if (val < 0x0002 || val > 0xFFFE || val % 2) | ||
| 105 | return -EINVAL; | ||
| 106 | |||
| 107 | if (val < hdev->sniff_min_interval) | ||
| 108 | return -EINVAL; | ||
| 109 | |||
| 110 | hdev->sniff_max_interval = val; | ||
| 111 | |||
| 112 | return count; | ||
| 113 | } | ||
| 114 | |||
| 115 | static ssize_t show_sniff_min_interval(struct class_device *cdev, char *buf) | ||
| 116 | { | ||
| 117 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 118 | return sprintf(buf, "%d\n", hdev->sniff_min_interval); | ||
| 119 | } | ||
| 120 | |||
| 121 | static ssize_t store_sniff_min_interval(struct class_device *cdev, const char *buf, size_t count) | ||
| 122 | { | ||
| 123 | struct hci_dev *hdev = class_get_devdata(cdev); | ||
| 124 | char *ptr; | ||
| 125 | __u16 val; | ||
| 126 | |||
| 127 | val = simple_strtoul(buf, &ptr, 10); | ||
| 128 | if (ptr == buf) | ||
| 129 | return -EINVAL; | ||
| 130 | |||
| 131 | if (val < 0x0002 || val > 0xFFFE || val % 2) | ||
| 132 | return -EINVAL; | ||
| 133 | |||
| 134 | if (val > hdev->sniff_max_interval) | ||
| 135 | return -EINVAL; | ||
| 136 | |||
| 137 | hdev->sniff_min_interval = val; | ||
| 138 | |||
| 139 | return count; | ||
| 140 | } | ||
| 141 | |||
| 64 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 142 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
| 65 | static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | 143 | static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL); |
| 66 | static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | 144 | static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL); |
| 67 | static CLASS_DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); | 145 | static CLASS_DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); |
| 68 | static CLASS_DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); | 146 | static CLASS_DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); |
| 69 | 147 | ||
| 148 | static CLASS_DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, | ||
| 149 | show_idle_timeout, store_idle_timeout); | ||
| 150 | static CLASS_DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, | ||
| 151 | show_sniff_max_interval, store_sniff_max_interval); | ||
| 152 | static CLASS_DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, | ||
| 153 | show_sniff_min_interval, store_sniff_min_interval); | ||
| 154 | |||
| 70 | static struct class_device_attribute *bt_attrs[] = { | 155 | static struct class_device_attribute *bt_attrs[] = { |
| 71 | &class_device_attr_name, | 156 | &class_device_attr_name, |
| 72 | &class_device_attr_type, | 157 | &class_device_attr_type, |
| 73 | &class_device_attr_address, | 158 | &class_device_attr_address, |
| 74 | &class_device_attr_flags, | 159 | &class_device_attr_flags, |
| 75 | &class_device_attr_inquiry_cache, | 160 | &class_device_attr_inquiry_cache, |
| 161 | &class_device_attr_idle_timeout, | ||
| 162 | &class_device_attr_sniff_max_interval, | ||
| 163 | &class_device_attr_sniff_min_interval, | ||
| 76 | NULL | 164 | NULL |
| 77 | }; | 165 | }; |
| 78 | 166 | ||
