From 6b813c7afe73d902c84ea83a48fdcccaef414150 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 8 Sep 2016 16:40:50 +0530 Subject: [PATCH 01/16] Bluetooth: Enable sniff mode for incoming connection Add provision to set the link poilicy to enable sniff mode for incoming connection. Change-Id: Ifff9e9f0838f26a6c96d81f4cbaae43429aa231f Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- net/bluetooth/hci_conn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3fd360c..70878a8 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -536,6 +536,11 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, conn->tx_power = HCI_TX_POWER_INVALID; conn->max_tx_power = HCI_TX_POWER_INVALID; +#ifdef TIZEN_BT + /* enable sniff mode for incoming connection */ + conn->link_policy = hdev->link_policy; +#endif + set_bit(HCI_CONN_POWER_SAVE, &conn->flags); conn->disc_timeout = HCI_DISCONN_TIMEOUT; -- 2.7.4 From 315ddd59d6694a8d22e55e06cd3eb8e2f3cc009b Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 8 Sep 2016 17:01:39 +0530 Subject: [PATCH 02/16] Bluetooth: Cancel the Sniff timer This patch adds code to cancel the sniff timer. Change-Id: I756d3b08acf6462044d1fb204064fe12ce1238c1 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- net/bluetooth/hci_conn.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 70878a8..551206f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1526,9 +1526,18 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) } timer: +#ifdef TIZEN_BT + if (hdev->idle_timeout > 0) { + /* Sniff timer cancel */ + cancel_delayed_work(&conn->idle_work); + queue_delayed_work(hdev->workqueue, &conn->idle_work, + msecs_to_jiffies(hdev->idle_timeout)); + } +#else if (hdev->idle_timeout > 0) queue_delayed_work(hdev->workqueue, &conn->idle_work, msecs_to_jiffies(hdev->idle_timeout)); +#endif } /* Drop all connection on the device */ -- 2.7.4 From 2cb61a3fefde33cbe6fb9b447da51e737eeb1204 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Mon, 12 Sep 2016 12:46:44 +0530 Subject: [PATCH 03/16] Bluetooth: Store the key if auth type is P192 This patch allows to store the key after authentication if auth type is "HCI_LK_AUTH_COMBINATION_P192" Change-Id: Ie44dbe7dfec361edab61aceaf9b2ca4057b88fa5 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- net/bluetooth/hci_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 95b801e..11b4905 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2351,6 +2351,14 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) return true; +#ifdef TIZEN_BT + /* In case of auth_type '0x01', it is authenticated by MITM. + * So store it. + */ + if (key_type == HCI_LK_AUTH_COMBINATION_P192) + return true; +#endif + /* If none of the above criteria match, then don't store the key * persistently */ return false; -- 2.7.4 From 0962d6826ebdfbc4df2bb837cdcbe051a99af96e Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 8 Sep 2016 16:21:01 +0530 Subject: [PATCH 04/16] Bluetooth: Fix issue in the Set LE privacy function. This patch fixes not to check the hdev power before setting LE Privacy. Change-Id: I344ea13b1d90527e3e7554ec616cdc640b85159c Signed-off-by: Sudha Bheemanna Signed-off-by: Seung-Woo Kim Signed-off-by: Amit Purwar --- net/bluetooth/mgmt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index dd3e7df..0dfe752 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -4955,9 +4955,14 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, MGMT_STATUS_INVALID_PARAMS); +#ifndef TIZEN_BT + /* commenting out since set privacy command is always rejected + * if this condition is enabled. + */ if (hdev_is_powered(hdev)) return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, MGMT_STATUS_REJECTED); +#endif hci_dev_lock(hdev); -- 2.7.4 From b70d293ffc27667bb21eaa4edb68e2eab1b95515 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 15 Sep 2016 10:12:09 +0530 Subject: [PATCH 05/16] Bluetooth: Add support to enable/disable IPSP This patch supports MGMT commands and code to enable or disable IPSP 6LowPan features. Change-Id: Ia866ecfa517c7d7e4320f17d94d80dfeb9261e59 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/l2cap.h | 11 +++++++++++ include/net/bluetooth/mgmt_tizen.h | 6 ++++++ net/bluetooth/6lowpan.c | 34 ++++++++++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 0697fd4..790b50d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -948,4 +948,15 @@ void l2cap_conn_put(struct l2cap_conn *conn); int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); +#ifdef TIZEN_BT +#ifdef CONFIG_BT_6LOWPAN +/* IPSP : initialize/deinitialize 6lowpan */ +void bt_6lowpan_enable(void); +void bt_6lowpan_disable(void); +#else +static inline void bt_6lowpan_enable(void) { } +static inline void bt_6lowpan_disable(void) { } +#endif +#endif /* TIZEN_BT */ + #endif /* __L2CAP_H */ diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 982c00d..6549be1 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -167,6 +167,12 @@ struct mgmt_rp_get_adv_tx_power { __s8 adv_tx_power; } __packed; +#define MGMT_OP_ENABLE_6LOWPAN (TIZEN_OP_CODE_BASE + 0x12) +struct mgmt_cp_enable_6lowpan { + __u8 enable_6lowpan; +} __packed; +#define MGMT_ENABLE_BT_6LOWPAN_SIZE 1 + /* EVENTS */ /* For device name update changes */ diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 4e2576f..a7b2937 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -1288,6 +1288,40 @@ static int __init bt_6lowpan_init(void) return register_netdevice_notifier(&bt_6lowpan_dev_notifier); } +#ifdef TIZEN_BT +void bt_6lowpan_enable(void) +{ + if (!enable_6lowpan) { + disconnect_all_peers(); + + enable_6lowpan = true; + + if (listen_chan) { + l2cap_chan_close(listen_chan, 0); + l2cap_chan_put(listen_chan); + } + + listen_chan = bt_6lowpan_listen(); + + register_netdevice_notifier(&bt_6lowpan_dev_notifier); + } +} + +void bt_6lowpan_disable(void) +{ + if (enable_6lowpan) { + if (listen_chan) { + l2cap_chan_close(listen_chan, 0); + l2cap_chan_put(listen_chan); + listen_chan = NULL; + } + disconnect_devices(); + unregister_netdevice_notifier(&bt_6lowpan_dev_notifier); + enable_6lowpan = false; + } +} +#endif + static void __exit bt_6lowpan_exit(void) { debugfs_remove(lowpan_enable_debugfs); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0dfe752..31ea0da 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6865,6 +6865,40 @@ void mgmt_multi_adv_state_change_evt(struct hci_dev *hdev, u8 adv_instance, sizeof(struct mgmt_ev_vendor_specific_multi_adv_state_changed), NULL); } + +static int enable_bt_6lowpan(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + int err; + struct mgmt_cp_enable_6lowpan *cp = data; + + BT_DBG("%s", hdev->name); + + hci_dev_lock(hdev); + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ENABLE_6LOWPAN, + MGMT_STATUS_NOT_POWERED); + goto unlocked; + } + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ENABLE_6LOWPAN, + MGMT_STATUS_NOT_SUPPORTED); + goto unlocked; + } + + if (cp->enable_6lowpan) + bt_6lowpan_enable(); + else + bt_6lowpan_disable(); + + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ENABLE_6LOWPAN, + MGMT_STATUS_SUCCESS, NULL, 0); +unlocked: + hci_dev_unlock(hdev); + return err; +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -8837,6 +8871,7 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { { le_set_scan_params, MGMT_LE_SET_SCAN_PARAMS_SIZE }, { set_voice_setting, MGMT_SET_VOICE_SETTING_SIZE }, { get_adv_tx_power, MGMT_GET_ADV_TX_POWER_SIZE }, + { enable_bt_6lowpan, MGMT_ENABLE_BT_6LOWPAN_SIZE }, }; #endif -- 2.7.4 From ae13651411e0b44f971d2bf64e951d3af44aab77 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 15 Sep 2016 12:53:03 +0530 Subject: [PATCH 06/16] Bluetooth: IPSP Connect/Disconnect apis This patch adds MGMT code to support IPSP connect and disconnect apis and handle connection state changed event. Change-Id: I1c41ec4f38cf9a108e443def3bc23c1b964e2985 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/hci_core.h | 2 + include/net/bluetooth/l2cap.h | 5 ++ include/net/bluetooth/mgmt_tizen.h | 18 +++++ net/bluetooth/6lowpan.c | 16 ++++ net/bluetooth/mgmt.c | 150 +++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 997c852..64bc47d 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1712,6 +1712,8 @@ void mgmt_le_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, u8 adv_type); void mgmt_multi_adv_state_change_evt(struct hci_dev *hdev, u8 adv_instance, u8 state_change_reason, u16 connection_handle); +void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16], + bdaddr_t *bdaddr, u8 addr_type, bool connected); #endif u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 790b50d..6b9f2f5 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -953,9 +953,14 @@ void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); /* IPSP : initialize/deinitialize 6lowpan */ void bt_6lowpan_enable(void); void bt_6lowpan_disable(void); +/* IPSP: Connect and Disconnect */ +int _bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type); +int _bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type); #else static inline void bt_6lowpan_enable(void) { } static inline void bt_6lowpan_disable(void) { } +static inline int _bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type) { return -ENODEV; } +static inline int _bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type) { return -ENODEV; } #endif #endif /* TIZEN_BT */ diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 6549be1..52a36f9 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -173,6 +173,18 @@ struct mgmt_cp_enable_6lowpan { } __packed; #define MGMT_ENABLE_BT_6LOWPAN_SIZE 1 +#define MGMT_OP_CONNECT_6LOWPAN (TIZEN_OP_CODE_BASE + 0x13) +struct mgmt_cp_connect_6lowpan { + struct mgmt_addr_info addr; +} __packed; +#define MGMT_CONNECT_6LOWPAN_SIZE 7 + +#define MGMT_OP_DISCONNECT_6LOWPAN (TIZEN_OP_CODE_BASE + 0x14) +struct mgmt_cp_disconnect_6lowpan { + struct mgmt_addr_info addr; +} __packed; +#define MGMT_DISCONNECT_6LOWPAN_SIZE 7 + /* EVENTS */ /* For device name update changes */ @@ -254,5 +266,11 @@ struct mgmt_ev_vendor_specific_multi_adv_state_changed { } __packed; /* LE advertisement state changed event */ +#define MGMT_EV_6LOWPAN_CONN_STATE_CHANGED (TIZEN_EV_BASE + 0x0c) +struct mgmt_ev_6lowpan_conn_state_changed { + struct mgmt_addr_info addr; + __u8 connected; + __u8 ifname[16]; +} __packed; #endif /* __MGMT_TIZEN_H */ diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index a7b2937..2804e4a 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -757,6 +757,12 @@ static inline void chan_ready_cb(struct l2cap_chan *chan) add_peer_chan(chan, dev, new_netdev); ifup(dev->netdev); + +#ifdef TIZEN_BT + /* IPSP: Send connection changed state info to bluez */ + mgmt_6lowpan_conn_changed(dev->hdev, dev->netdev->name, &chan->dst, + chan->dst_type, true); +#endif } static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan) @@ -1320,6 +1326,16 @@ void bt_6lowpan_disable(void) enable_6lowpan = false; } } + +int _bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type) +{ + return bt_6lowpan_connect(addr, dst_type); +} + +int _bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type) +{ + return bt_6lowpan_disconnect(conn, dst_type); +} #endif static void __exit bt_6lowpan_exit(void) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 31ea0da..ade871f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6899,6 +6899,154 @@ unlocked: hci_dev_unlock(hdev); return err; } + +static int connect_bt_6lowpan(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + struct mgmt_cp_connect_6lowpan *cp = data; + __u8 addr_type = ADDR_LE_DEV_PUBLIC; + int err; + + BT_DBG("%s", hdev->name); + + hci_dev_lock(hdev); + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, + MGMT_STATUS_NOT_SUPPORTED); + goto unlocked; + } + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, + MGMT_STATUS_REJECTED); + goto unlocked; + } + + if (bdaddr_type_is_le(cp->addr.type)) { + if (cp->addr.type == BDADDR_LE_PUBLIC) + addr_type = ADDR_LE_DEV_PUBLIC; + else + addr_type = ADDR_LE_DEV_RANDOM; + } else { + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, + MGMT_STATUS_INVALID_PARAMS, NULL, 0); + goto unlocked; + } + + hci_dev_unlock(hdev); + + /* 6lowpan Connect */ + err = _bt_6lowpan_connect(&cp->addr.bdaddr, cp->addr.type); + + hci_dev_lock(hdev); + + if (err < 0) { + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, + MGMT_STATUS_REJECTED, NULL, 0); + + goto unlocked; + } + + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, 0, + NULL, 0); +unlocked: + hci_dev_unlock(hdev); + return err; +} + +static int disconnect_bt_6lowpan(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + struct mgmt_cp_disconnect_6lowpan *cp = data; + struct hci_conn *conn = NULL; + __u8 addr_type = ADDR_LE_DEV_PUBLIC; + int err; + + BT_DBG("%s", hdev->name); + + hci_dev_lock(hdev); + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_NOT_SUPPORTED); + goto unlocked; + } + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_REJECTED); + goto unlocked; + } + + if (bdaddr_type_is_le(cp->addr.type)) { + if (cp->addr.type == BDADDR_LE_PUBLIC) + addr_type = ADDR_LE_DEV_PUBLIC; + else + addr_type = ADDR_LE_DEV_RANDOM; + } else { + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_INVALID_PARAMS, NULL, 0); + goto unlocked; + } + + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); + if (!conn) { + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_NOT_CONNECTED, NULL, 0); + goto unlocked; + } + + if (conn->dst_type != addr_type) { + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_INVALID_PARAMS, NULL, 0); + goto unlocked; + } + + if (conn->state != BT_CONNECTED) { + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_NOT_CONNECTED, NULL, 0); + goto unlocked; + } + + /* 6lowpan Disconnect */ + err = _bt_6lowpan_disconnect(conn->l2cap_data, cp->addr.type); + if (err < 0) { + err = mgmt_cmd_complete(sk, hdev->id, + MGMT_OP_DISCONNECT_6LOWPAN, + MGMT_STATUS_REJECTED, NULL, 0); + goto unlocked; + } + + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONNECT_6LOWPAN, 0, + NULL, 0); + +unlocked: + hci_dev_unlock(hdev); + return err; +} + +void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16], + bdaddr_t *bdaddr, u8 addr_type, bool connected) +{ + char buf[512]; + struct mgmt_ev_6lowpan_conn_state_changed *ev = (void *)buf; + size_t ev_size; + + memset(buf, 0, sizeof(buf)); + bacpy(&ev->addr.bdaddr, bdaddr); + ev->addr.type = addr_type; + ev->connected = connected; + memcpy(ev->ifname, (__u8 *)if_name, 16); + + ev_size = sizeof(*ev); + + mgmt_event(MGMT_EV_6LOWPAN_CONN_STATE_CHANGED, hdev, ev, ev_size, NULL); +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -8872,6 +9020,8 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { { set_voice_setting, MGMT_SET_VOICE_SETTING_SIZE }, { get_adv_tx_power, MGMT_GET_ADV_TX_POWER_SIZE }, { enable_bt_6lowpan, MGMT_ENABLE_BT_6LOWPAN_SIZE }, + { connect_bt_6lowpan, MGMT_CONNECT_6LOWPAN_SIZE }, + { disconnect_bt_6lowpan, MGMT_DISCONNECT_6LOWPAN_SIZE }, }; #endif -- 2.7.4 From a2835b3330899dbcc8ef0b70c6d77f5d955a59fb Mon Sep 17 00:00:00 2001 From: "h.sandeep" Date: Fri, 16 Sep 2016 14:45:24 +0530 Subject: [PATCH 07/16] Bluetooth: Fix IPSP connection callback event issue. This patch fixes the IPSP connection callback event issue between kernel and bluez layer. Change-Id: Ia4d625aa8a6dbc9da89a7d9f12308af9c90d0594 Signed-off-by: h.sandeep Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- net/bluetooth/l2cap_core.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2c6eabf..06453f5 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1259,8 +1259,23 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) * case of receiving data before the L2CAP info req/rsp * procedure is complete. */ +#ifndef TIZEN_BT if (chan->state == BT_CONNECTED) return; +#else + if (chan->state == BT_CONNECTED) { + if (chan->psm == L2CAP_PSM_IPSP) { + struct l2cap_conn *conn = chan->conn; + + if (conn->hcon->out) + return; + else if (conn->hcon->type != LE_LINK) + return; + } else { + return; + } + } +#endif /* This clears all conf flags, including CONF_NOT_COMPLETE */ chan->conf_state = 0; @@ -6859,8 +6874,23 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, * procdure is done simply assume that the channel is supported * and mark it as ready. */ +#ifndef TIZEN_BT if (chan->chan_type == L2CAP_CHAN_FIXED) l2cap_chan_ready(chan); +#else + if (chan->chan_type == L2CAP_CHAN_FIXED) { + if (chan->psm == L2CAP_PSM_IPSP) { + struct l2cap_conn *conn = chan->conn; + + if (conn->hcon->out) + l2cap_chan_ready(chan); + else if (conn->hcon->type != LE_LINK) + l2cap_chan_ready(chan); + } else { + l2cap_chan_ready(chan); + } + } +#endif if (chan->state != BT_CONNECTED) goto drop; -- 2.7.4 From 2058b5e7c5bb9bc65964ff4266293f6ce6e984e9 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Fri, 16 Sep 2016 10:38:30 +0530 Subject: [PATCH 08/16] Bluetooth: Read LE Max data length command This patch adds the MGMT command and code to support reading the maximum data length supported command for LE. Change-Id: I4dc0041f2070de2ccb6a4164c8823612863c941e Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/hci_core.h | 2 + include/net/bluetooth/mgmt_tizen.h | 9 +++++ net/bluetooth/hci_event.c | 9 +++++ net/bluetooth/mgmt.c | 79 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 64bc47d..8bf3e7c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1714,6 +1714,8 @@ void mgmt_multi_adv_state_change_evt(struct hci_dev *hdev, u8 adv_instance, u8 state_change_reason, u16 connection_handle); void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16], bdaddr_t *bdaddr, u8 addr_type, bool connected); +void mgmt_le_read_maximum_data_length_complete(struct hci_dev *hdev, + u8 status); #endif u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 52a36f9..444d793 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -185,6 +185,15 @@ struct mgmt_cp_disconnect_6lowpan { } __packed; #define MGMT_DISCONNECT_6LOWPAN_SIZE 7 +#define MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH (TIZEN_OP_CODE_BASE + 0x15) +struct mgmt_rp_le_read_maximum_data_length { + __le16 max_tx_octets; + __le16 max_tx_time; + __le16 max_rx_octets; + __le16 max_rx_time; +} __packed; +#define MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE 0 + /* EVENTS */ /* For device name update changes */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5d91a25..2790b30 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1532,13 +1532,22 @@ static void hci_cc_le_read_max_data_len(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); +#ifndef TIZEN_BT if (rp->status) return; +#else + hci_dev_lock(hdev); +#endif hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); + +#ifdef TIZEN_BT + mgmt_le_read_maximum_data_length_complete(hdev, rp->status); + hci_dev_unlock(hdev); +#endif } static void hci_cc_write_le_host_supported(struct hci_dev *hdev, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index ade871f..757d978 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7047,6 +7047,83 @@ void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16], mgmt_event(MGMT_EV_6LOWPAN_CONN_STATE_CHANGED, hdev, ev, ev_size, NULL); } + +void mgmt_le_read_maximum_data_length_complete(struct hci_dev *hdev, u8 status) +{ + struct mgmt_pending_cmd *cmd; + struct mgmt_rp_le_read_maximum_data_length rp; + + BT_DBG("%s status %u", hdev->name, status); + + cmd = pending_find(MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, hdev); + if (!cmd) + return; + + if (status) + mgmt_cmd_status(cmd->sk, hdev->id, + MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, + mgmt_status(status)); + + memset(&rp, 0, sizeof(rp)); + + rp.max_tx_octets = cpu_to_le16(hdev->le_max_tx_len); + rp.max_tx_time = cpu_to_le16(hdev->le_max_tx_time); + rp.max_rx_octets = cpu_to_le16(hdev->le_max_rx_len); + rp.max_rx_time = cpu_to_le16(hdev->le_max_rx_time); + + mgmt_cmd_complete(cmd->sk, hdev->id, + MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, 0, + &rp, sizeof(rp)); + + mgmt_pending_remove(cmd); +} + +static int read_maximum_le_data_length(struct sock *sk, + struct hci_dev *hdev, void *data, u16 len) +{ + struct mgmt_pending_cmd *cmd; + int err; + + BT_DBG("read_maximum_le_data_length %s", hdev->name); + + hci_dev_lock(hdev); + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, + MGMT_STATUS_NOT_POWERED); + goto unlock; + } + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, + MGMT_STATUS_NOT_SUPPORTED); + goto unlock; + } + + if (pending_find(MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, + MGMT_STATUS_BUSY); + goto unlock; + } + + cmd = mgmt_pending_add(sk, MGMT_OP_LE_READ_MAXIMUM_DATA_LENGTH, + hdev, data, len); + if (!cmd) { + err = -ENOMEM; + goto unlock; + } + + err = hci_send_cmd(hdev, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); + if (err < 0) + mgmt_pending_remove(cmd); + +unlock: + hci_dev_unlock(hdev); + return err; +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -9022,6 +9099,8 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { { enable_bt_6lowpan, MGMT_ENABLE_BT_6LOWPAN_SIZE }, { connect_bt_6lowpan, MGMT_CONNECT_6LOWPAN_SIZE }, { disconnect_bt_6lowpan, MGMT_DISCONNECT_6LOWPAN_SIZE }, + { read_maximum_le_data_length, + MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE }, }; #endif -- 2.7.4 From f41aa46442aef616ee05a83c4e7e189a5cd2bc00 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Fri, 16 Sep 2016 12:09:57 +0530 Subject: [PATCH 09/16] Bluetooth: Write host suggested default le data length This patch adds MGMT command and code for supporting write default le data length command to the controller. Change-Id: I3d2c8b622b7913a3ed542342e3ba8076c30dc279 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/hci_core.h | 2 + include/net/bluetooth/mgmt_tizen.h | 7 ++++ net/bluetooth/hci_event.c | 13 ++++++ net/bluetooth/mgmt.c | 86 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 8bf3e7c..b4cf072 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1716,6 +1716,8 @@ void mgmt_6lowpan_conn_changed(struct hci_dev *hdev, char if_name[16], bdaddr_t *bdaddr, u8 addr_type, bool connected); void mgmt_le_read_maximum_data_length_complete(struct hci_dev *hdev, u8 status); +void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev, + u8 status); #endif u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 444d793..0f36ecd 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -194,6 +194,13 @@ struct mgmt_rp_le_read_maximum_data_length { } __packed; #define MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE 0 +#define MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH (TIZEN_OP_CODE_BASE + 0x16) +struct mgmt_cp_le_write_host_suggested_data_length { + __le16 def_tx_octets; + __le16 def_tx_time; +} __packed; +#define MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE 4 + /* EVENTS */ /* For device name update changes */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2790b30..10b63f6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1465,14 +1465,27 @@ static void hci_cc_le_write_def_data_len(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, status); if (status) +#ifndef TIZEN_BT return; +#else + goto unblock; +#endif sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); if (!sent) +#ifndef TIZEN_BT return; +#else + goto unblock; +#endif hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); + +#ifdef TIZEN_BT +unblock: + mgmt_le_write_host_suggested_data_length_complete(hdev, status); +#endif } static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 757d978..693c014 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7124,6 +7124,90 @@ unlock: hci_dev_unlock(hdev); return err; } + +void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev, + u8 status) +{ + struct mgmt_pending_cmd *cmd; + + BT_DBG("status 0x%02x", status); + + hci_dev_lock(hdev); + + cmd = pending_find(MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, hdev); + if (!cmd) { + BT_ERR("cmd not found in the pending list"); + goto unlock; + } + + if (status) + mgmt_cmd_status(cmd->sk, hdev->id, + MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + mgmt_status(status)); + else + mgmt_cmd_complete(cmd->sk, hdev->id, + MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + 0, NULL, 0); + + mgmt_pending_remove(cmd); + +unlock: + hci_dev_unlock(hdev); +} + +static int write_host_suggested_le_data_length(struct sock *sk, + struct hci_dev *hdev, void *data, u16 len) +{ + struct mgmt_pending_cmd *cmd; + struct mgmt_cp_le_write_host_suggested_data_length *cp = data; + struct hci_cp_le_write_def_data_len hci_data; + int err = 0; + + BT_DBG("Write host suggested data length request for %s", hdev->name); + + hci_dev_lock(hdev); + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_NOT_POWERED); + goto unlock; + } + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_NOT_SUPPORTED); + goto unlock; + } + + if (pending_find(MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_BUSY); + goto unlock; + } + + cmd = mgmt_pending_add(sk, MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, + hdev, data, len); + if (!cmd) { + err = -ENOMEM; + goto unlock; + } + + hci_data.tx_len = cp->def_tx_octets; + hci_data.tx_time = cp->def_tx_time; + + err = hci_send_cmd(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN, + sizeof(hci_data), &hci_data); + if (err < 0) + mgmt_pending_remove(cmd); + +unlock: + hci_dev_unlock(hdev); + + return err; +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -9101,6 +9185,8 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { { disconnect_bt_6lowpan, MGMT_DISCONNECT_6LOWPAN_SIZE }, { read_maximum_le_data_length, MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE }, + { write_host_suggested_le_data_length, + MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE }, }; #endif -- 2.7.4 From 324f26665f8ebace18f26ed93cd40aa63fcc8744 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Fri, 16 Sep 2016 12:54:31 +0530 Subject: [PATCH 10/16] Bluetooth: Read host suggested default le data length This patch adds MGMT command and code for supporting reading default le data length value set at the controller. Change-Id: I2b81982dc26ed5af4a8f8a3d3913db5d64625260 Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/hci_core.h | 2 + include/net/bluetooth/mgmt_tizen.h | 7 ++++ net/bluetooth/hci_event.c | 10 +++++ net/bluetooth/mgmt.c | 81 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b4cf072..cdb4b7d 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1718,6 +1718,8 @@ void mgmt_le_read_maximum_data_length_complete(struct hci_dev *hdev, u8 status); void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev, u8 status); +void mgmt_le_read_host_suggested_data_length_complete(struct hci_dev *hdev, + u8 status); #endif u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 0f36ecd..2d11d5b 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -201,6 +201,13 @@ struct mgmt_cp_le_write_host_suggested_data_length { } __packed; #define MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE 4 +#define MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH (TIZEN_OP_CODE_BASE + 0x17) +struct mgmt_rp_le_read_host_suggested_data_length { + __le16 def_tx_octets; + __le16 def_tx_time; +} __packed; +#define MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE 0 + /* EVENTS */ /* For device name update changes */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 10b63f6..82bcc68 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1449,11 +1449,21 @@ static void hci_cc_le_read_def_data_len(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); +#ifdef TIZEN_BT + hci_dev_lock(hdev); +#else if (rp->status) return; +#endif hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); + +#ifdef TIZEN_BT + mgmt_le_read_host_suggested_data_length_complete(hdev, rp->status); + + hci_dev_unlock(hdev); +#endif } static void hci_cc_le_write_def_data_len(struct hci_dev *hdev, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 693c014..a449faf 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7208,6 +7208,85 @@ unlock: return err; } + +void mgmt_le_read_host_suggested_data_length_complete(struct hci_dev *hdev, + u8 status) +{ + struct mgmt_pending_cmd *cmd; + struct mgmt_rp_le_read_host_suggested_data_length rp; + + BT_DBG("%s status %u", hdev->name, status); + + cmd = pending_find(MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, hdev); + if (!cmd) { + BT_ERR("cmd not found in the pending list"); + return; + } + + if (status) + mgmt_cmd_status(cmd->sk, hdev->id, + MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, + mgmt_status(status)); + + memset(&rp, 0, sizeof(rp)); + + rp.def_tx_octets = cpu_to_le16(hdev->le_def_tx_len); + rp.def_tx_time = cpu_to_le16(hdev->le_def_tx_time); + + mgmt_cmd_complete(cmd->sk, hdev->id, + MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, 0, + &rp, sizeof(rp)); + + mgmt_pending_remove(cmd); +} + +static int read_host_suggested_data_length(struct sock *sk, + struct hci_dev *hdev, void *data, u16 len) +{ + struct mgmt_pending_cmd *cmd; + int err; + + BT_DBG("read_host_suggested_data_length %s", hdev->name); + + hci_dev_lock(hdev); + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_NOT_POWERED); + goto unlock; + } + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_NOT_SUPPORTED); + goto unlock; + } + + if (pending_find(MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, hdev)) { + err = mgmt_cmd_status(sk, hdev->id, + MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, + MGMT_STATUS_BUSY); + goto unlock; + } + + cmd = mgmt_pending_add(sk, MGMT_OP_LE_READ_HOST_SUGGESTED_DATA_LENGTH, + hdev, data, len); + if (!cmd) { + err = -ENOMEM; + goto unlock; + } + + err = hci_send_cmd(hdev, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL); + if (err < 0) + mgmt_pending_remove(cmd); + +unlock: + hci_dev_unlock(hdev); + + return err; +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -9187,6 +9266,8 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE }, { write_host_suggested_le_data_length, MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE }, + { read_host_suggested_data_length, + MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE }, }; #endif -- 2.7.4 From bde01c80dd511923f0b4d0149fb557e5ad193da0 Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Fri, 16 Sep 2016 15:37:22 +0530 Subject: [PATCH 11/16] Bluetooth: Set le data length command and event Sets the data length for the le data packet with in the advised limits. MGMT command and event are added to handle the setting of data length. Change-Id: Ia5c2167743cc9a29190e5631973e9d52d41caa1d Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- include/net/bluetooth/hci_core.h | 14 ++++++ include/net/bluetooth/mgmt_tizen.h | 23 +++++++++ net/bluetooth/hci_conn.c | 29 ++++++++++++ net/bluetooth/hci_event.c | 30 ++++++++++++ net/bluetooth/mgmt.c | 95 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index cdb4b7d..7096f3c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -508,6 +508,12 @@ struct hci_conn { __u8 remote_id; unsigned int sent; +#ifdef TIZEN_BT + __u16 tx_len; + __u16 tx_time; + __u16 rx_len; + __u16 rx_time; +#endif struct sk_buff_head data_q; struct list_head chan_list; @@ -559,6 +565,10 @@ struct hci_conn_params { u16 conn_latency; u16 supervision_timeout; +#ifdef TIZEN_BT + u16 max_tx_octets; + u16 max_tx_time; +#endif enum { HCI_AUTO_CONN_DISABLED, HCI_AUTO_CONN_REPORT, @@ -1720,6 +1730,10 @@ void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev, u8 status); void mgmt_le_read_host_suggested_data_length_complete(struct hci_dev *hdev, u8 status); +void mgmt_le_data_length_change_complete(struct hci_dev *hdev, + bdaddr_t *bdaddr, u16 tx_octets, u16 tx_time, + u16 rx_octets, u16 rx_time); +int hci_le_set_data_length(struct hci_conn *conn, u16 tx_octets, u16 tx_time); #endif u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index 2d11d5b..cfb9d50 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -208,6 +208,20 @@ struct mgmt_rp_le_read_host_suggested_data_length { } __packed; #define MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE 0 +#define MGMT_OP_LE_SET_DATA_LENGTH (TIZEN_OP_CODE_BASE + 0x18) +struct mgmt_cp_le_set_data_length { + bdaddr_t bdaddr; + __le16 max_tx_octets; + __le16 max_tx_time; +} __packed; +#define MGMT_LE_SET_DATA_LENGTH_SIZE 10 + +struct mgmt_rp_le_set_data_length { + __u8 status; + __le16 handle; +} __packed; +#define MGMT_LE_SET_DATA_LENGTH_RSP_SIZE 3 + /* EVENTS */ /* For device name update changes */ @@ -296,4 +310,13 @@ struct mgmt_ev_6lowpan_conn_state_changed { __u8 ifname[16]; } __packed; +#define MGMT_EV_LE_DATA_LENGTH_CHANGED (TIZEN_EV_BASE + 0x0d) +struct mgmt_ev_le_data_length_changed { + struct mgmt_addr_info addr; + __le16 max_tx_octets; + __le16 max_tx_time; + __le16 max_rx_octets; + __le16 max_rx_time; +} __packed; + #endif /* __MGMT_TIZEN_H */ diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 551206f..9a7490f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1504,6 +1504,35 @@ int hci_conn_change_supervision_timeout(struct hci_conn *conn, __u16 timeout) return 0; } + +int hci_le_set_data_length(struct hci_conn *conn, u16 tx_octets, u16 tx_time) +{ + struct hci_dev *hdev = conn->hdev; + struct hci_conn_params *params; + struct hci_cp_le_set_data_len cp; + + hci_dev_lock(hdev); + + params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); + if (params) { + params->max_tx_octets = tx_octets; + params->max_tx_time = tx_time; + } + + hci_dev_unlock(hdev); + + memset(&cp, 0, sizeof(cp)); + cp.handle = cpu_to_le16(conn->handle); + cp.tx_len = cpu_to_le16(tx_octets); + cp.tx_time = cpu_to_le16(tx_time); + + hci_send_cmd(hdev, HCI_OP_LE_SET_DATA_LEN, sizeof(cp), &cp); + + if (params) + return 0x01; + + return 0x00; +} #endif /* Enter active mode */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 82bcc68..7b699e2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1748,6 +1748,31 @@ static void hci_vendor_specific_evt(struct hci_dev *hdev, struct sk_buff *skb) break; } } + +static void hci_le_data_length_changed_complete_evt(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_ev_le_data_len_change *ev = (void *)skb->data; + struct hci_conn *conn; + + BT_DBG("%s status", hdev->name); + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); + if (conn) { + conn->tx_len = le16_to_cpu(ev->tx_len); + conn->tx_time = le16_to_cpu(ev->tx_time); + conn->rx_len = le16_to_cpu(ev->rx_len); + conn->rx_time = le16_to_cpu(ev->rx_time); + } + + mgmt_le_data_length_change_complete(hdev, &conn->dst, + conn->tx_len, conn->tx_time, + conn->rx_len, conn->rx_time); + + hci_dev_unlock(hdev); +} #endif static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) @@ -5922,6 +5947,11 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) case HCI_EV_LE_EXT_ADV_SET_TERM: hci_le_ext_adv_term_evt(hdev, skb); break; +#ifdef TIZEN_BT + case HCI_EV_LE_DATA_LEN_CHANGE: + hci_le_data_length_changed_complete_evt(hdev, skb); + break; +#endif default: break; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a449faf..6a6befe 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7287,6 +7287,99 @@ unlock: return err; } + +static int set_le_data_length_params(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + struct mgmt_cp_le_set_data_length *cp = data; + struct mgmt_rp_le_set_data_length *rp; + struct mgmt_pending_cmd *cmd; + struct hci_conn *conn; + int err = 0; + u16 max_tx_octets, max_tx_time; + size_t rp_len; + + BT_INFO("Set Data length for the device %s", hdev->name); + + hci_dev_lock(hdev); + + rp_len = sizeof(*rp); + rp = kmalloc(rp_len, GFP_KERNEL); + if (!rp) { + err = -ENOMEM; + goto unlock; + } + + if (!hdev_is_powered(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_LE_SET_DATA_LENGTH, + MGMT_STATUS_NOT_POWERED); + goto unlock; + } + + if (!lmp_le_capable(hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_LE_SET_DATA_LENGTH, + MGMT_STATUS_NOT_SUPPORTED); + goto unlock; + } + + if (pending_find(MGMT_OP_LE_SET_DATA_LENGTH, hdev)) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_LE_SET_DATA_LENGTH, + MGMT_STATUS_BUSY); + goto unlock; + } + + cmd = mgmt_pending_add(sk, MGMT_OP_LE_SET_DATA_LENGTH, hdev, data, len); + if (!cmd) { + err = -ENOMEM; + goto unlock; + } + + max_tx_octets = __le16_to_cpu(cp->max_tx_octets); + max_tx_time = __le16_to_cpu(cp->max_tx_time); + + BT_DBG("max_tx_octets 0x%4.4x max_tx_time 0x%4.4x latency", + max_tx_octets, max_tx_time); + + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr); + if (!conn) { + mgmt_cmd_status(sk, hdev->id, MGMT_OP_LE_SET_DATA_LENGTH, + MGMT_STATUS_NOT_CONNECTED); + goto unlock; + } + + hci_dev_unlock(hdev); + + err = hci_le_set_data_length(conn, max_tx_octets, max_tx_time); + if (err < 0) + mgmt_pending_remove(cmd); + + rp->handle = conn->handle; + rp->status = 0; + + hci_dev_lock(hdev); + err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LE_SET_DATA_LENGTH, 0, + rp, rp_len); +unlock: + kfree(rp); + hci_dev_unlock(hdev); + + return err; +} + +void mgmt_le_data_length_change_complete(struct hci_dev *hdev, + bdaddr_t *bdaddr, u16 tx_octets, u16 tx_time, + u16 rx_octets, u16 rx_time) +{ + struct mgmt_ev_le_data_length_changed ev; + + bacpy(&ev.addr.bdaddr, bdaddr); + ev.max_tx_octets = tx_octets; + ev.max_tx_time = tx_time; + ev.max_rx_octets = rx_octets; + ev.max_rx_time = rx_time; + + mgmt_event(MGMT_EV_LE_DATA_LENGTH_CHANGED, hdev, &ev, sizeof(ev), NULL); +} #endif /* TIZEN_BT */ static bool ltk_is_valid(struct mgmt_ltk_info *key) @@ -9268,6 +9361,8 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE }, { read_host_suggested_data_length, MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE }, + { set_le_data_length_params, + MGMT_LE_SET_DATA_LENGTH_SIZE }, }; #endif -- 2.7.4 From b2f6ad21a0bab8e59926666f717a4f6c53066a2d Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Tue, 2 Jul 2019 11:08:59 +0900 Subject: [PATCH 12/16] ARM: dts: bcm27xx: Fix to of_graph from bridge node for panel Beginning with kernel v4.15, the i2c management of the touchscreen panel driver has been changed to use of_graph from brdge node. So change to of_graph and remove the unnecessary nodes. Change-Id: Ibf131aebd964360874ebe2f3792f0912f6e8988d Signed-off-by: Hoegeun Kwon --- arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 6 ------ arch/arm/boot/dts/bcm270x.dtsi | 19 +++++++++++++------ arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 6 ------ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 ------ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 6 ------ 5 files changed, 13 insertions(+), 30 deletions(-) diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts index 976ad46d..89bbd53 100644 --- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts @@ -180,10 +180,4 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; - - pitouchscreen: panel@0 { - compatible = "raspberrypi,touchscreen"; - reg = <0>; - raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; - }; }; diff --git a/arch/arm/boot/dts/bcm270x.dtsi b/arch/arm/boot/dts/bcm270x.dtsi index 6f19c64..1d09f66 100644 --- a/arch/arm/boot/dts/bcm270x.dtsi +++ b/arch/arm/boot/dts/bcm270x.dtsi @@ -162,14 +162,15 @@ #size-cells = <0>; status = "disabled"; - pitouchscreen_bridge: bridge@45 { - compatible = "raspberrypi,touchscreen-bridge-i2c"; + lcd@45 { + compatible = "raspberrypi,7inch-touchscreen-panel"; reg = <0x45>; - }; - pitouchscreen_touch: bridge@38 { - compatible = "raspberrypi,touchscreen-ts-i2c"; - reg = <0x38>; + port { + panel_dsi_port: endpoint { + remote-endpoint = <&dsi_out_port>; + }; + }; }; }; @@ -205,4 +206,10 @@ &dsi1 { power-domains = <&power RPI_POWER_DOMAIN_DSI1>; + + port { + dsi_out_port: endpoint { + remote-endpoint = <&panel_dsi_port>; + }; + }; }; diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts index f024be1..6787a00 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts @@ -346,10 +346,4 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; - - pitouchscreen: panel@0 { - compatible = "raspberrypi,touchscreen"; - reg = <0>; - raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; - }; }; diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts index 62327354..10a2a49 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts @@ -357,10 +357,4 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; - - pitouchscreen: panel@0 { - compatible = "raspberrypi,touchscreen"; - reg = <0>; - raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; - }; }; diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts index cb2e16d..ec376ee 100644 --- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts @@ -140,12 +140,6 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; - - pitouchscreen: panel@0 { - compatible = "raspberrypi,touchscreen"; - reg = <0>; - raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; - }; }; }; -- 2.7.4 From aa7ccee8cb9def4d3866ff7a9cdcca60b5ec2f60 Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Wed, 3 Jul 2019 19:22:11 +0900 Subject: [PATCH 13/16] Revert "ARM: dts: bcm27xx: Fix to of_graph from bridge node for panel" This reverts commit b2f6ad21a0bab8e59926666f717a4f6c53066a2d. There is a problem with the hdmi and revert the patch. Change-Id: Ia69d10c067ff69d192162b0598f43028c4a05f9b Signed-off-by: Hoegeun Kwon --- arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 6 ++++++ arch/arm/boot/dts/bcm270x.dtsi | 19 ++++++------------- arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 6 ++++++ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 ++++++ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 6 ++++++ 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts index 89bbd53..976ad46d 100644 --- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts @@ -180,4 +180,10 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; + + pitouchscreen: panel@0 { + compatible = "raspberrypi,touchscreen"; + reg = <0>; + raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; + }; }; diff --git a/arch/arm/boot/dts/bcm270x.dtsi b/arch/arm/boot/dts/bcm270x.dtsi index 1d09f66..6f19c64 100644 --- a/arch/arm/boot/dts/bcm270x.dtsi +++ b/arch/arm/boot/dts/bcm270x.dtsi @@ -162,15 +162,14 @@ #size-cells = <0>; status = "disabled"; - lcd@45 { - compatible = "raspberrypi,7inch-touchscreen-panel"; + pitouchscreen_bridge: bridge@45 { + compatible = "raspberrypi,touchscreen-bridge-i2c"; reg = <0x45>; + }; - port { - panel_dsi_port: endpoint { - remote-endpoint = <&dsi_out_port>; - }; - }; + pitouchscreen_touch: bridge@38 { + compatible = "raspberrypi,touchscreen-ts-i2c"; + reg = <0x38>; }; }; @@ -206,10 +205,4 @@ &dsi1 { power-domains = <&power RPI_POWER_DOMAIN_DSI1>; - - port { - dsi_out_port: endpoint { - remote-endpoint = <&panel_dsi_port>; - }; - }; }; diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts index 6787a00..f024be1 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts @@ -346,4 +346,10 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; + + pitouchscreen: panel@0 { + compatible = "raspberrypi,touchscreen"; + reg = <0>; + raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; + }; }; diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts index 10a2a49..62327354 100644 --- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts @@ -357,4 +357,10 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; + + pitouchscreen: panel@0 { + compatible = "raspberrypi,touchscreen"; + reg = <0>; + raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; + }; }; diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts index ec376ee..cb2e16d 100644 --- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts @@ -140,6 +140,12 @@ #address-cells = <1>; #size-cells = <0>; status = "okay"; + + pitouchscreen: panel@0 { + compatible = "raspberrypi,touchscreen"; + reg = <0>; + raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; + }; }; }; -- 2.7.4 From 5410fa1888028986cef4edfed467780a980be8c6 Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Wed, 3 Jul 2019 14:18:50 +0900 Subject: [PATCH 14/16] tools: Add build script for ARM kernel of rpi3 Add build script for ARM kernel of rpi3. Change-Id: I35a7dd2148350f775d3d96a478dac66190079d68 Signed-off-by: Hoegeun Kwon --- build-rpi3-arm32.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 build-rpi3-arm32.sh diff --git a/build-rpi3-arm32.sh b/build-rpi3-arm32.sh new file mode 100755 index 0000000..1e8c02a --- /dev/null +++ b/build-rpi3-arm32.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Check this system has ccache +check_ccache() +{ + type ccache + if [ "$?" -eq "0" ]; then + CCACHE=ccache + fi +} + +check_ccache + +rm -f arch/arm/boot/zImage +rm -f arch/arm/boot/dts/*.dtb + +if ! [ -e .config ] ; then + make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- tizen_bcm2709_defconfig +fi + +make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8 + +if [ ! -f "./arch/arm/boot/zImage" ]; then + echo "Build fail" + exit 1 +fi -- 2.7.4 From 09499eb15be25af1b0b59bdcdc5ceb2e6eda8585 Mon Sep 17 00:00:00 2001 From: DoHyun Pyun Date: Thu, 4 Jul 2019 09:18:21 +0900 Subject: [PATCH 15/16] Bluetooth: Fix the potential crash issue There is a logic error in the event function. We should check the callback function's parameter before calling. Change-Id: I06a4a8c50317e5ec4ae8fe35e4b788105e090196 Fixes: bde01c80dd51 ("Bluetooth: Set le data length command and event") Signed-off-by: DoHyun Pyun --- net/bluetooth/hci_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 7b699e2..de15177 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1765,11 +1765,11 @@ static void hci_le_data_length_changed_complete_evt(struct hci_dev *hdev, conn->tx_time = le16_to_cpu(ev->tx_time); conn->rx_len = le16_to_cpu(ev->rx_len); conn->rx_time = le16_to_cpu(ev->rx_time); - } - mgmt_le_data_length_change_complete(hdev, &conn->dst, + mgmt_le_data_length_change_complete(hdev, &conn->dst, conn->tx_len, conn->tx_time, conn->rx_len, conn->rx_time); + } hci_dev_unlock(hdev); } -- 2.7.4 From 986793fd7f354927b0aa2c336cc9d3089d157aac Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Wed, 3 Jul 2019 14:16:46 +0900 Subject: [PATCH 16/16] ARM: configs: tizen_bcm2709_defconfig: Remove unused modules Remove unused modules from the backlight. Change-Id: I1fd5267690efd4a7bd5137b64dfadba5111dc2dd Signed-off-by: Hoegeun Kwon --- arch/arm/configs/tizen_bcm2709_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/tizen_bcm2709_defconfig b/arch/arm/configs/tizen_bcm2709_defconfig index bc661a7..7905932 100644 --- a/arch/arm/configs/tizen_bcm2709_defconfig +++ b/arch/arm/configs/tizen_bcm2709_defconfig @@ -269,7 +269,6 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_RPI=y -CONFIG_BACKLIGHT_GPIO=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set -- 2.7.4