Bluetooth: Write host suggested default le data length
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / net / bluetooth / mgmt.c
index 2892254..bcb5448 100644 (file)
@@ -7064,6 +7064,90 @@ unlock:
        hci_dev_unlock(hdev);
        return err;
 }
+
+void mgmt_le_write_host_suggested_data_length_complete(struct hci_dev *hdev,
+               u8 status)
+{
+       struct pending_cmd *cmd;
+
+       BT_DBG("status 0x%02x", status);
+
+       hci_dev_lock(hdev);
+
+       cmd = mgmt_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)
+               cmd_status(cmd->sk, hdev->id,
+                               MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH,
+                               mgmt_status(status));
+       else
+               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 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 = 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 = cmd_status(sk, hdev->id,
+                               MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH,
+                               MGMT_STATUS_NOT_SUPPORTED);
+               goto unlock;
+       }
+
+       if (mgmt_pending_find(MGMT_OP_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH, hdev)) {
+               err = 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;
+}
 /* END TIZEN_Bluetooth */
 #endif
 
@@ -8169,6 +8253,8 @@ static const struct mgmt_handler tizen_mgmt_handlers[] = {
        { enable_bt_6lowpan,       false, MGMT_ENABLE_BT_6LOWPAN_SIZE },
        { disconnect_bt_6lowpan,   false, MGMT_DISCONNECT_6LOWPAN_SIZE },
        { read_maximum_le_data_length, false, MGMT_LE_READ_MAXIMUM_DATA_LENGTH_SIZE },
+       { write_host_suggested_le_data_length, false,
+                       MGMT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH_SIZE },
 };
 #endif