Re: [PATCH BlueZ 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Pauli,

On Thu, Jul 27, 2023 at 3:00 AM Pauli Virtanen <pav@xxxxxx> wrote:
>
> to, 2023-07-27 kello 00:25 +0300, Pauli Virtanen kirjoitti:
> > Create Connection Cancel shall return Command Complete with error status
> > when there is no Create Connection that can be canceled.  In these
> > cases, we should not send a (spurious) Connection Complete event.
> >
> > Fix by keeping a list of pending Create Connection commands, and
> > returning command errors if there is none pending at the moment.
> > ---
> >  emulator/btdev.c | 76 +++++++++++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 68 insertions(+), 8 deletions(-)
> >
> > diff --git a/emulator/btdev.c b/emulator/btdev.c
> > index 637f0bb98..0c75e71c0 100644
> > --- a/emulator/btdev.c
> > +++ b/emulator/btdev.c
> > @@ -62,6 +62,7 @@ struct hook {
> >
> >  #define MAX_HOOK_ENTRIES 16
> >  #define MAX_EXT_ADV_SETS 3
> > +#define MAX_PENDING_CONN 16
> >
> >  struct btdev_conn {
> >       uint16_t handle;
> > @@ -223,6 +224,8 @@ struct btdev {
> >       uint8_t  le_rl_enable;
> >       uint16_t le_rl_timeout;
> >
> > +     struct btdev *pending_conn[MAX_PENDING_CONN];
> > +
> >       uint8_t le_local_sk256[32];
> >
> >       uint16_t sync_train_interval;
> > @@ -1211,10 +1214,36 @@ static struct btdev_conn *conn_link_bis(struct btdev *dev, struct btdev *remote,
> >       return conn;
> >  }
> >
> > +static void pending_conn_add(struct btdev *btdev, struct btdev *remote)
> > +{
> > +     int i;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
> > +             if (!btdev->pending_conn[i]) {
> > +                     btdev->pending_conn[i] = remote;
> > +                     return;
> > +             }
> > +     }
> > +}
> > +
> > +static bool pending_conn_del(struct btdev *btdev, struct btdev *remote)
> > +{
> > +     int i;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
> > +             if (btdev->pending_conn[i] == remote) {
> > +                     btdev->pending_conn[i] = NULL;
> > +                     return true;
> > +             }
> > +     }
> > +     return false;
> > +}
> > +
> >  static void conn_complete(struct btdev *btdev,
> >                                       const uint8_t *bdaddr, uint8_t status)
> >  {
> >       struct bt_hci_evt_conn_complete cc;
> > +     struct btdev *remote = find_btdev_by_bdaddr(bdaddr);
> >
> >       if (!status) {
> >               struct btdev_conn *conn;
> > @@ -1223,6 +1252,8 @@ static void conn_complete(struct btdev *btdev,
> >               if (!conn)
> >                       return;
> >
> > +             pending_conn_del(conn->link->dev, btdev);
> > +
> >               cc.status = status;
> >               memcpy(cc.bdaddr, btdev->bdaddr, 6);
> >               cc.encr_mode = 0x00;
> > @@ -1240,6 +1271,8 @@ static void conn_complete(struct btdev *btdev,
> >               cc.link_type = 0x01;
> >       }
> >
> > +     pending_conn_del(btdev, remote);
> > +
> >       cc.status = status;
> >       memcpy(cc.bdaddr, bdaddr, 6);
> >       cc.encr_mode = 0x00;
> > @@ -1260,6 +1293,8 @@ static int cmd_create_conn_complete(struct btdev *dev, const void *data,
> >               memcpy(cr.dev_class, dev->dev_class, 3);
> >               cr.link_type = 0x01;
> >
> > +             pending_conn_add(dev, remote);
> > +
> >               send_event(remote, BT_HCI_EVT_CONN_REQUEST, &cr, sizeof(cr));
> >       } else {
> >               conn_complete(dev, cmd->bdaddr, BT_HCI_ERR_PAGE_TIMEOUT);
> > @@ -1296,14 +1331,47 @@ static int cmd_add_sco_conn(struct btdev *dev, const void *data, uint8_t len)
> >       cc.encr_mode = 0x00;
> >
> >  done:
> > +     pending_conn_del(dev, conn->link->dev);
> > +
> >       send_event(dev, BT_HCI_EVT_CONN_COMPLETE, &cc, sizeof(cc));
> >
> >       return 0;
> >  }
> >
> > +static bool match_bdaddr(const void *data, const void *match_data)
> > +{
> > +     const struct btdev_conn *conn = data;
> > +     const uint8_t *bdaddr = match_data;
> > +
> > +     return !memcmp(conn->link->dev->bdaddr, bdaddr, 6);
> > +}
> > +
> >  static int cmd_create_conn_cancel(struct btdev *dev, const void *data,
> >                                                       uint8_t len)
> >  {
> > +     const struct bt_hci_cmd_create_conn_cancel *cmd = data;
> > +     struct btdev *remote = find_btdev_by_bdaddr(cmd->bdaddr);
> > +     struct btdev_conn *conn;
> > +
> > +     /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 1848
> > +      *
> > +      * If the connection is already established, and the
> > +      * HCI_Connection_Complete event has been sent, then the Controller
> > +      * shall return an HCI_Command_Complete event with the error code
> > +      * Connection Already Exists (0x0B). If the HCI_Create_Connection_Cancel
> > +      * command is sent to the Controller without a preceding
> > +      * HCI_Create_Connection command to the same device, the BR/EDR
> > +      * Controller shall return an HCI_Command_Complete event with the error
> > +      * code Unknown Connection Identifier (0x02).
> > +      */
> > +     if (!pending_conn_del(dev, remote)) {
> > +             conn = queue_find(dev->conns, match_bdaddr, cmd->bdaddr);
> > +             if (conn)
> > +                     return -EEXIST;
> > +
> > +             return -ENOENT;
> > +     }
> > +
> >       cmd_status(dev, BT_HCI_ERR_SUCCESS, BT_HCI_CMD_CREATE_CONN_CANCEL);
>
> This should have been Command_Complete not Command_Status.

There is quite a few errors when Ive tried to compile this one:

emulator/btdev.c: In function ‘pending_conn_add’:
emulator/btdev.c:1221:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1221 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
emulator/btdev.c: In function ‘pending_conn_del’:
emulator/btdev.c:1233:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1233 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
cc1: all warnings being treated as errors
emulator/btdev.c: In function ‘pending_conn_add’:
emulator/btdev.c:1221:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1221 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
emulator/btdev.c: In function ‘pending_conn_del’:
emulator/btdev.c:1233:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1233 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
cc1: all warnings being treated as errors
make[1]: *** [Makefile:8484: emulator/android_android_tester-btdev.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: *** [Makefile:7648: emulator/btdev.o] Error 1
emulator/btdev.c: In function ‘pending_conn_add’:
emulator/btdev.c:1221:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1221 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
emulator/btdev.c: In function ‘pending_conn_del’:
emulator/btdev.c:1233:23: error: comparison of integer expressions of
different signedness: ‘int’ and ‘long unsigned int’
[-Werror=sign-compare]
 1233 |         for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
      |                       ^
cc1: all warnings being treated as errors


> For v2

Please have the errors fixed as well.

> >
> >       return 0;
> > @@ -1372,14 +1440,6 @@ static int cmd_link_key_reply(struct btdev *dev, const void *data, uint8_t len)
> >       return 0;
> >  }
> >
> > -static bool match_bdaddr(const void *data, const void *match_data)
> > -{
> > -     const struct btdev_conn *conn = data;
> > -     const uint8_t *bdaddr = match_data;
> > -
> > -     return !memcmp(conn->link->dev->bdaddr, bdaddr, 6);
> > -}
> > -
> >  static void auth_complete(struct btdev_conn *conn, uint8_t status)
> >  {
> >       struct bt_hci_evt_auth_complete ev;
>


-- 
Luiz Augusto von Dentz




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux