linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ] btdev: Fix using the callback return as command complete
@ 2021-10-22 22:27 Luiz Augusto von Dentz
  2021-10-25 18:21 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 2+ messages in thread
From: Luiz Augusto von Dentz @ 2021-10-22 22:27 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Command callback can only be used when generating a command status as
command complete can carry more than just the status.
---
 emulator/btdev.c | 120 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 84 insertions(+), 36 deletions(-)

diff --git a/emulator/btdev.c b/emulator/btdev.c
index e129b5cda..7b311f347 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -3677,12 +3677,16 @@ static int cmd_add_al(struct btdev *dev, const void *data, uint8_t len)
 	 * HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
 	 * command is outstanding.
 	 */
-	if (!al_can_change(dev))
-		return -EPERM;
+	if (!al_can_change(dev)) {
+		status = BT_HCI_ERR_COMMAND_DISALLOWED;
+		goto done;
+	}
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	for (i = 0; i < dev->le_al_len; i++) {
 		struct btdev_al *al = &dev->le_al[i];
@@ -3694,18 +3698,25 @@ static int cmd_add_al(struct btdev *dev, const void *data, uint8_t len)
 			pos = i;
 	}
 
-	if (exists)
-		return -EALREADY;
+	/* If the device is already in the Filter Accept List, the Controller
+	 * should not add the device to the Filter Accept List again and should
+	 * return success.
+	 */
+	if (exists) {
+		status = BT_HCI_ERR_SUCCESS;
+		goto done;
+	}
 
 	if (pos < 0) {
-		cmd_status(dev, BT_HCI_ERR_MEM_CAPACITY_EXCEEDED,
-					BT_HCI_CMD_LE_ADD_TO_ACCEPT_LIST);
-		return 0;
+		status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
+		goto done;
 	}
 
 	al_add(&dev->le_al[pos], cmd->addr_type, (bdaddr_t *)&cmd->addr);
 
 	status = BT_HCI_ERR_SUCCESS;
+
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_ADD_TO_ACCEPT_LIST,
 						&status, sizeof(status));
 
@@ -3728,12 +3739,16 @@ static int cmd_remove_al(struct btdev *dev, const void *data, uint8_t len)
 	 * HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
 	 * command is outstanding.
 	 */
-	if (!al_can_change(dev))
-		return -EPERM;
+	if (!al_can_change(dev)) {
+		status = BT_HCI_ERR_COMMAND_DISALLOWED;
+		goto done;
+	}
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	for (i = 0; i < dev->le_al_len; i++) {
 		struct btdev_al *al = &dev->le_al[i];
@@ -3750,10 +3765,14 @@ static int cmd_remove_al(struct btdev *dev, const void *data, uint8_t len)
 		}
 	}
 
-	if (i == dev->le_al_len)
-		return -EINVAL;
+	if (i == dev->le_al_len) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	status = BT_HCI_ERR_SUCCESS;
+
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_REMOVE_FROM_ACCEPT_LIST,
 						&status, sizeof(status));
 
@@ -3774,12 +3793,16 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
 	 * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
 	 * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
 	 */
-	if (dev->le_adv_enable || dev->le_scan_enable)
-		return -EPERM;
+	if (dev->le_adv_enable || dev->le_scan_enable) {
+		status = BT_HCI_ERR_COMMAND_DISALLOWED;
+		goto done;
+	}
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	for (i = 0; i < dev->le_rl_len; i++) {
 		struct btdev_rl *rl = &dev->le_rl[i];
@@ -3791,13 +3814,18 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
 			pos = i;
 	}
 
-	if (exists)
-		return -EALREADY;
+	/* If an entry already exists in the resolving list with the same four
+	 * parameter values, the Controller shall either reject the command or
+	 * not add the device to the resolving list again and return success.
+	 */
+	if (exists) {
+		status = BT_HCI_ERR_SUCCESS;
+		goto done;
+	}
 
 	if (pos < 0) {
-		cmd_status(dev, BT_HCI_ERR_MEM_CAPACITY_EXCEEDED,
-					BT_HCI_CMD_LE_ADD_TO_RESOLV_LIST);
-		return 0;
+		status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
+		goto done;
 	}
 
 	dev->le_rl[pos].type = cmd->addr_type;
@@ -3806,6 +3834,8 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
 	memcpy(dev->le_rl[pos].local_irk, cmd->local_irk, 16);
 
 	status = BT_HCI_ERR_SUCCESS;
+
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_ADD_TO_RESOLV_LIST,
 						&status, sizeof(status));
 
@@ -3825,12 +3855,16 @@ static int cmd_remove_rl(struct btdev *dev, const void *data, uint8_t len)
 	 * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
 	 * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
 	 */
-	if (dev->le_adv_enable || dev->le_scan_enable)
-		return -EPERM;
+	if (dev->le_adv_enable || dev->le_scan_enable) {
+		status = BT_HCI_ERR_COMMAND_DISALLOWED;
+		goto done;
+	}
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	for (i = 0; i < dev->le_rl_len; i++) {
 		struct btdev_rl *rl = &dev->le_rl[i];
@@ -3841,10 +3875,14 @@ static int cmd_remove_rl(struct btdev *dev, const void *data, uint8_t len)
 		}
 	}
 
-	if (i == dev->le_rl_len)
-		return -EINVAL;
+	if (i == dev->le_rl_len) {
+		status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	status = BT_HCI_ERR_SUCCESS;
+
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_REMOVE_FROM_RESOLV_LIST,
 						&status, sizeof(status));
 
@@ -3862,12 +3900,16 @@ static int cmd_clear_rl(struct btdev *dev, const void *data, uint8_t len)
 	 * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
 	 * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
 	 */
-	if (dev->le_adv_enable || dev->le_scan_enable)
-		return -EPERM;
+	if (dev->le_adv_enable || dev->le_scan_enable) {
+		status = BT_HCI_ERR_COMMAND_DISALLOWED;
+		goto done;
+	}
 
 	rl_clear(dev);
 
 	status = BT_HCI_ERR_SUCCESS;
+
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_CLEAR_RESOLV_LIST,
 						&status, sizeof(status));
 
@@ -3894,12 +3936,15 @@ static int cmd_read_peer_rl_addr(struct btdev *dev, const void *data,
 	struct bt_hci_rsp_le_read_peer_resolv_addr rsp;
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		rsp.status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
 	memset(rsp.addr, 0, 6);
 
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_READ_PEER_RESOLV_ADDR,
 							&rsp, sizeof(rsp));
 
@@ -3913,12 +3958,15 @@ static int cmd_read_local_rl_addr(struct btdev *dev, const void *data,
 	struct bt_hci_rsp_le_read_local_resolv_addr rsp;
 
 	/* Valid range for address type is 0x00 to 0x01 */
-	if (cmd->addr_type > 0x01)
-		return -EINVAL;
+	if (cmd->addr_type > 0x01) {
+		rsp.status = BT_HCI_ERR_INVALID_PARAMETERS;
+		goto done;
+	}
 
 	rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
 	memset(rsp.addr, 0, 6);
 
+done:
 	cmd_complete(dev, BT_HCI_CMD_LE_READ_LOCAL_RESOLV_ADDR,
 							&rsp, sizeof(rsp));
 
-- 
2.31.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH BlueZ] btdev: Fix using the callback return as command complete
  2021-10-22 22:27 [PATCH BlueZ] btdev: Fix using the callback return as command complete Luiz Augusto von Dentz
@ 2021-10-25 18:21 ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 2+ messages in thread
From: Luiz Augusto von Dentz @ 2021-10-25 18:21 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

On Fri, Oct 22, 2021 at 3:27 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> Command callback can only be used when generating a command status as
> command complete can carry more than just the status.
> ---
>  emulator/btdev.c | 120 +++++++++++++++++++++++++++++++++--------------
>  1 file changed, 84 insertions(+), 36 deletions(-)
>
> diff --git a/emulator/btdev.c b/emulator/btdev.c
> index e129b5cda..7b311f347 100644
> --- a/emulator/btdev.c
> +++ b/emulator/btdev.c
> @@ -3677,12 +3677,16 @@ static int cmd_add_al(struct btdev *dev, const void *data, uint8_t len)
>          * HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
>          * command is outstanding.
>          */
> -       if (!al_can_change(dev))
> -               return -EPERM;
> +       if (!al_can_change(dev)) {
> +               status = BT_HCI_ERR_COMMAND_DISALLOWED;
> +               goto done;
> +       }
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         for (i = 0; i < dev->le_al_len; i++) {
>                 struct btdev_al *al = &dev->le_al[i];
> @@ -3694,18 +3698,25 @@ static int cmd_add_al(struct btdev *dev, const void *data, uint8_t len)
>                         pos = i;
>         }
>
> -       if (exists)
> -               return -EALREADY;
> +       /* If the device is already in the Filter Accept List, the Controller
> +        * should not add the device to the Filter Accept List again and should
> +        * return success.
> +        */
> +       if (exists) {
> +               status = BT_HCI_ERR_SUCCESS;
> +               goto done;
> +       }
>
>         if (pos < 0) {
> -               cmd_status(dev, BT_HCI_ERR_MEM_CAPACITY_EXCEEDED,
> -                                       BT_HCI_CMD_LE_ADD_TO_ACCEPT_LIST);
> -               return 0;
> +               status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
> +               goto done;
>         }
>
>         al_add(&dev->le_al[pos], cmd->addr_type, (bdaddr_t *)&cmd->addr);
>
>         status = BT_HCI_ERR_SUCCESS;
> +
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_ADD_TO_ACCEPT_LIST,
>                                                 &status, sizeof(status));
>
> @@ -3728,12 +3739,16 @@ static int cmd_remove_al(struct btdev *dev, const void *data, uint8_t len)
>          * HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
>          * command is outstanding.
>          */
> -       if (!al_can_change(dev))
> -               return -EPERM;
> +       if (!al_can_change(dev)) {
> +               status = BT_HCI_ERR_COMMAND_DISALLOWED;
> +               goto done;
> +       }
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         for (i = 0; i < dev->le_al_len; i++) {
>                 struct btdev_al *al = &dev->le_al[i];
> @@ -3750,10 +3765,14 @@ static int cmd_remove_al(struct btdev *dev, const void *data, uint8_t len)
>                 }
>         }
>
> -       if (i == dev->le_al_len)
> -               return -EINVAL;
> +       if (i == dev->le_al_len) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         status = BT_HCI_ERR_SUCCESS;
> +
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_REMOVE_FROM_ACCEPT_LIST,
>                                                 &status, sizeof(status));
>
> @@ -3774,12 +3793,16 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
>          * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
>          * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
>          */
> -       if (dev->le_adv_enable || dev->le_scan_enable)
> -               return -EPERM;
> +       if (dev->le_adv_enable || dev->le_scan_enable) {
> +               status = BT_HCI_ERR_COMMAND_DISALLOWED;
> +               goto done;
> +       }
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         for (i = 0; i < dev->le_rl_len; i++) {
>                 struct btdev_rl *rl = &dev->le_rl[i];
> @@ -3791,13 +3814,18 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
>                         pos = i;
>         }
>
> -       if (exists)
> -               return -EALREADY;
> +       /* If an entry already exists in the resolving list with the same four
> +        * parameter values, the Controller shall either reject the command or
> +        * not add the device to the resolving list again and return success.
> +        */
> +       if (exists) {
> +               status = BT_HCI_ERR_SUCCESS;
> +               goto done;
> +       }
>
>         if (pos < 0) {
> -               cmd_status(dev, BT_HCI_ERR_MEM_CAPACITY_EXCEEDED,
> -                                       BT_HCI_CMD_LE_ADD_TO_RESOLV_LIST);
> -               return 0;
> +               status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
> +               goto done;
>         }
>
>         dev->le_rl[pos].type = cmd->addr_type;
> @@ -3806,6 +3834,8 @@ static int cmd_add_rl(struct btdev *dev, const void *data, uint8_t len)
>         memcpy(dev->le_rl[pos].local_irk, cmd->local_irk, 16);
>
>         status = BT_HCI_ERR_SUCCESS;
> +
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_ADD_TO_RESOLV_LIST,
>                                                 &status, sizeof(status));
>
> @@ -3825,12 +3855,16 @@ static int cmd_remove_rl(struct btdev *dev, const void *data, uint8_t len)
>          * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
>          * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
>          */
> -       if (dev->le_adv_enable || dev->le_scan_enable)
> -               return -EPERM;
> +       if (dev->le_adv_enable || dev->le_scan_enable) {
> +               status = BT_HCI_ERR_COMMAND_DISALLOWED;
> +               goto done;
> +       }
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         for (i = 0; i < dev->le_rl_len; i++) {
>                 struct btdev_rl *rl = &dev->le_rl[i];
> @@ -3841,10 +3875,14 @@ static int cmd_remove_rl(struct btdev *dev, const void *data, uint8_t len)
>                 }
>         }
>
> -       if (i == dev->le_rl_len)
> -               return -EINVAL;
> +       if (i == dev->le_rl_len) {
> +               status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         status = BT_HCI_ERR_SUCCESS;
> +
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_REMOVE_FROM_RESOLV_LIST,
>                                                 &status, sizeof(status));
>
> @@ -3862,12 +3900,16 @@ static int cmd_clear_rl(struct btdev *dev, const void *data, uint8_t len)
>          * • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection,
>          * or HCI_LE_Periodic_Advertising_Create_Sync command is outstanding.
>          */
> -       if (dev->le_adv_enable || dev->le_scan_enable)
> -               return -EPERM;
> +       if (dev->le_adv_enable || dev->le_scan_enable) {
> +               status = BT_HCI_ERR_COMMAND_DISALLOWED;
> +               goto done;
> +       }
>
>         rl_clear(dev);
>
>         status = BT_HCI_ERR_SUCCESS;
> +
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_CLEAR_RESOLV_LIST,
>                                                 &status, sizeof(status));
>
> @@ -3894,12 +3936,15 @@ static int cmd_read_peer_rl_addr(struct btdev *dev, const void *data,
>         struct bt_hci_rsp_le_read_peer_resolv_addr rsp;
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               rsp.status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
>         memset(rsp.addr, 0, 6);
>
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_READ_PEER_RESOLV_ADDR,
>                                                         &rsp, sizeof(rsp));
>
> @@ -3913,12 +3958,15 @@ static int cmd_read_local_rl_addr(struct btdev *dev, const void *data,
>         struct bt_hci_rsp_le_read_local_resolv_addr rsp;
>
>         /* Valid range for address type is 0x00 to 0x01 */
> -       if (cmd->addr_type > 0x01)
> -               return -EINVAL;
> +       if (cmd->addr_type > 0x01) {
> +               rsp.status = BT_HCI_ERR_INVALID_PARAMETERS;
> +               goto done;
> +       }
>
>         rsp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
>         memset(rsp.addr, 0, 6);
>
> +done:
>         cmd_complete(dev, BT_HCI_CMD_LE_READ_LOCAL_RESOLV_ADDR,
>                                                         &rsp, sizeof(rsp));
>
> --
> 2.31.1

Pushed.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-25 18:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-22 22:27 [PATCH BlueZ] btdev: Fix using the callback return as command complete Luiz Augusto von Dentz
2021-10-25 18:21 ` Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).