Back to Zephyr

Bluetooth: GAP Shell

doc/connectivity/bluetooth/shell/host/gap.rst

4.4.015.3 KB
Original Source

Bluetooth: GAP Shell ####################

The GAP shell is the "main" shell of Bluetooth and handles connection management, scanning, advertising, and more.

Identities


Identities are a Zephyr host concept, allowing a single physical device to behave like multiple logical Bluetooth devices.

The shell allows the creation of multiple identities, to a maximum that is set by the Kconfig symbol :kconfig:option:CONFIG_BT_ID_MAX. To create a new identity, use :code:bt id-create command. You can then use it by selecting it with its ID :code:bt id-select <id>. Finally, you can list all the available identities with :code:id-show.

Scan for devices


Start scanning by using the :code:bt scan on command. Depending on the environment you're in, you may see a lot of lines printed on the shell. To stop the scan, run :code:bt scan off, the scrolling should stop.

Here is an example of what you can expect:

.. code-block:: console

    uart:~$ bt scan on
    Bluetooth active scan enabled
    [DEVICE]: CB:01:1A:2D:6E:AE (random), AD evt type 0, RSSI -78  C:1 S:1 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 20:C2:EE:59:85:5B (random), AD evt type 3, RSSI -62  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: E3:72:76:87:2F:E8 (random), AD evt type 3, RSSI -74  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 1E:19:25:8A:CB:84 (random), AD evt type 3, RSSI -67  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 26:42:F3:D5:A0:86 (random), AD evt type 3, RSSI -73  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 0C:61:D1:B9:5D:9E (random), AD evt type 3, RSSI -87  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 20:C2:EE:59:85:5B (random), AD evt type 3, RSSI -66  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    [DEVICE]: 25:3F:7A:EE:0F:55 (random), AD evt type 3, RSSI -83  C:0 S:0 D:0 SR:0 E:0 Prim: LE 1M, Secn: No packets, Interval: 0x0000 (0 us), SID: 0xff
    uart:~$ bt scan off
    Scan successfully stopped

As you can see, this can lead to a high number of results. To reduce that number and easily find a specific device, you can enable scan filters. There are four types of filters: by name, by RSSI, by address and by periodic advertising interval. To apply a filter, use the :code:bt scan-set-filter command followed by the type of filters. You can add multiple filters by using the commands again.

For example, if you want to look only for devices with the name test shell:

.. code-block:: console

    uart:~$ bt scan-filter-set name "test shell"

Or if you want to look for devices at a very close range:

.. code-block:: console

    uart:~$ bt scan-filter-set rssi -40
    RSSI cutoff set at -40 dB

Finally, if you want to remove all filters:

.. code-block:: console

    uart:~$ bt scan-filter-clear all

You can use the command :code:bt scan on to create an active scanner, meaning that the scanner will ask the advertisers for more information by sending a scan request packet. Alternatively, you can create a passive scanner by using the :code:bt scan passive command, so the scanner will not ask the advertiser for more information.

Connecting to a device


To connect to a device, you need to know its address and type of address and use the :code:bt connect command with the address and the type as arguments.

Here is an example:

.. code-block:: console

    uart:~$ bt connect 52:84:F6:BD:CE:48 random
    Connection pending
    Connected: 52:84:F6:BD:CE:48 (random)
    Remote LMP version 5.3 (0x0c) subversion 0xffff manufacturer 0x05f1
    LE Features: 0x000000000001412f
    LE PHY updated: TX PHY LE 2M, RX PHY LE 2M
    LE conn  param req: int (0x0018, 0x0028) lat 0 to 42
    LE conn param updated: int 0x0028 lat 0 to 42

You can list the active connections of the shell using the :code:bt connections command. The shell maximum number of connections is defined by :kconfig:option:CONFIG_BT_MAX_CONN. You can disconnect from a connection with the :code:bt disconnect <address: XX:XX:XX:XX:XX:XX> <type: (public|random)> command.

.. note::

    If you were scanning just before, you can connect to the last scanned device by
    simply running the :code:`bt connect` command.

    Alternatively, you can use the :code:`bt connect-name <name>` command to automatically
    enable scanning with a name filter and connect to the first match.

Advertising


Begin advertising by using the :code:bt advertise on command. This will use the default parameters and advertise a resolvable private address with the name of the device. You can choose to use the identity address instead by running the :code:bt advertise on identity command. To stop advertising use the :code:bt advertise off command.

To enable more advanced features of advertising, you should create an advertiser using the :code:bt adv-create command. Parameters for the advertiser can be passed either at the creation of it or by using the :code:bt adv-param command. To begin advertising with this newly created advertiser, use the :code:bt adv-start command, and then the :code:bt adv-stop command to stop advertising.

When using the custom advertisers, you can choose if it will be connectable or scannable. This leads to four options: :code:conn-scan, :code:conn-nscan, :code:nconn-scan and :code:nconn-nscan. Those parameters are mandatory when creating an advertiser or updating its parameters.

For example, if you want to create a connectable and scannable advertiser and start it:

.. code-block:: console

    uart:~$ bt adv-create conn-scan
    Created adv id: 0, adv: 0x200022f0
    uart:~$ bt adv-start
    Advertiser[0] 0x200022f0 set started

You may notice that with this, the custom advertiser does not advertise the device name; you need to add it. Continuing from the previous example:

.. code-block:: console

    uart:~$ bt adv-stop
    Advertiser set stopped
    uart:~$ bt adv-data dev-name
    uart:~$ bt adv-start
    Advertiser[0] 0x200022f0 set started

You should now see the name of the device in the advertising data. You can also set a custom name by using :code:name <custom name> instead of :code:dev-name. It is also possible to set the advertising data manually with the :code:bt adv-data command. The following example shows how to set the advertiser name with it using raw advertising data:

.. code-block:: console

    uart:~$ bt adv-create conn-scan
    Created adv id: 0, adv: 0x20002348
    uart:~$ bt adv-data 1009426C7565746F6F74682D5368656C6C
    uart:~$ bt adv-start
    Advertiser[0] 0x20002348 set started

The data must be formatted according to the Bluetooth Core Specification (see version 5.3, vol. 3, part C, 11). In this example, the first octet is the size of the data (the data and one octet for the data type), the second one is the type of data, 0x09 is the Complete Local Name and the remaining data are the name in ASCII. So, on the other device you should see the name Bluetooth-Shell.

When advertising, if others devices use an active scanner, you may receive scan request packets. To visualize those packets, you can add :code:scan-reports to the parameters of your advertiser.

Directed Advertising

It is possible to use directed advertising on the shell if you want to reconnect to a device. The following example demonstrates how to create a directed advertiser with the address specified right after the parameter :code:directed. The :code:low parameter indicates that we want to use the low duty cycle mode, and the :code:dir-rpa parameter is required if the remote device is privacy-enabled and supports address resolution of the target address in directed advertisement.

.. code-block:: console

    uart:~$ bt adv-create conn-scan directed D7:54:03:CE:F3:B4 random low dir-rpa
    Created adv id: 0, adv: 0x20002348

After that, you can start the advertiser and then the target device will be able to reconnect.

Extended Advertising

Let's now have a look at some extended advertising features. To enable extended advertising, use the ext-adv parameter.

.. code-block:: console

    uart:~$ bt adv-create conn-nscan ext-adv
    Created adv id: 0, adv: 0x200022f0
    uart:~$ bt adv-start
    Advertiser[0] 0x200022f0 set started

This will create an extended advertiser, that is connectable and non-scannable.

Encrypted Advertising Data

Zephyr has support for the Encrypted Advertising Data feature. The :code:bt encrypted-ad sub-commands allow managing the advertising data of a given advertiser.

To encrypt the advertising data, key materials need to be provided, that can be done with :code:bt encrypted-ad set-keys <session key> <init vector>. The session key is 16 bytes long and the initialisation vector is 8 bytes long.

You can add advertising data by using :code:bt encrypted-ad add-ad and :code:bt encrypted-ad add-ead. The former will take add one advertising data structure (as defined in the Core Specification), when the later will read the given data, encrypt them and then add the generated encrypted advertising data structure. It's possible to mix encrypted and non-encrypted data, when done adding advertising data, :code:bt encrypted-ad commit-ad can be used to apply the change to the data to the selected advertiser. After that the advertiser can be started as described previously. It's possible to clear the advertising data by using :code:bt encrypted-ad clear-ad.

On the Central side, it's possible to decrypt the received encrypted advertising data by setting the correct keys material as described earlier and then enabling the decrypting of the data with :code:bt encrypted-ad decrypt-scan on.

.. note::

    To see the advertising data in the scan report :code:`bt scan-verbose-output` need to be
    enabled.

.. note::

    It's possible to increase the length of the advertising data by increasing the value of
    :kconfig:option:`CONFIG_BT_CTLR_ADV_DATA_LEN_MAX` and
    :kconfig:option:`CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX`.

Here is a simple example demonstrating the usage of EAD:

.. tabs::

    .. group-tab:: Peripheral

            .. code-block:: console

                    uart:~$ bt init
                    ...
                    uart:~$ bt adv-create conn-nscan ext-adv
                    Created adv id: 0, adv: 0x81769a0
                    uart:~$ bt encrypted-ad set-keys 9ba22d3824efc70feb800c80294cba38 2e83f3d4d47695b6
                    session key set to:
                    00000000: 9b a2 2d 38 24 ef c7 0f  eb 80 0c 80 29 4c ba 38 |..-8$... ....)L.8|
                    initialisation vector set to:
                    00000000: 2e 83 f3 d4 d4 76 95 b6                          |.....v..         |
                    uart:~$ bt encrypted-ad add-ad 06097368656C6C
                    uart:~$ bt encrypted-ad add-ead 03ffdead03ffbeef
                    uart:~$ bt encrypted-ad commit-ad
                    Advertising data for Advertiser[0] 0x81769a0 updated.
                    uart:~$ bt adv-start
                    Advertiser[0] 0x81769a0 set started

    .. group-tab:: Central

            .. code-block:: console

                    uart:~$ bt init
                    ...
                    uart:~$ bt scan-verbose-output on
                    uart:~$ bt encrypted-ad set-keys 9ba22d3824efc70feb800c80294cba38 2e83f3d4d47695b6
                    session key set to:
                    00000000: 9b a2 2d 38 24 ef c7 0f  eb 80 0c 80 29 4c ba 38 |..-8$... ....)L.8|
                    initialisation vector set to:
                    00000000: 2e 83 f3 d4 d4 76 95 b6                          |.....v..         |
                    uart:~$ bt encrypted-ad decrypt-scan on
                    Received encrypted advertising data will now be decrypted using provided key materials.
                    uart:~$ bt scan on
                    Bluetooth active scan enabled
                    [DEVICE]: 68:49:30:68:49:30 (random), AD evt type 5, RSSI -59   shell C:1 S:0 D:0 SR:0 E:1 Prim: LE 1M, Secn: LE 2M, Interval: 0x0000 (0 us), SID: 0x0
                            [SCAN DATA START - EXT_ADV]
                            Type 0x09:    shell
                            Type 0x31: Encrypted Advertising Data: 0xe2, 0x17, 0xed, 0x04, 0xe7, 0x02, 0x1d, 0xc9, 0x40, 0x07, uart:~0x18, 0x90, 0x6c, 0x4b, 0xfe, 0x34, 0xad
                            [START DECRYPTED DATA]
                            Type 0xff: 0xde, 0xad
                            Type 0xff: 0xbe, 0xef
                            [END DECRYPTED DATA]
                            [SCAN DATA END]
                    ...

Filter Accept List


It's possible to create a list of allowed addresses that can be used to connect to those addresses automatically. Here is how to do it:

.. code-block:: console

    uart:~$ bt fal-add 47:38:76:EA:29:36 random
    uart:~$ bt fal-add 66:C8:80:2A:05:73 random
    uart:~$ bt fal-connect on

The shell will then connect to the first available device. In the example, if both devices are advertising at the same time, we will connect to the first address added to the list.

The Filter Accept List can also be used for scanning or advertising by using the option :code:fal. For example, if we want to scan for a bunch of selected addresses, we can set up a Filter Accept List:

.. code-block:: console

    uart:~$ bt fal-add 65:4B:9E:83:AF:73 random
    uart:~$ bt fal-add 73:72:82:B4:8F:B9 random
    uart:~$ bt fal-add 5D:85:50:1C:72:64 random
    uart:~$ bt scan on fal

You should see only those three addresses reported by the scanner.

Enabling security


When connected to a device, you can enable multiple levels of security, here is the list for Bluetooth LE:

  • 1 No encryption and no authentication;
  • 2 Encryption and no authentication;
  • 3 Encryption and authentication;
  • 4 Bluetooth LE Secure Connection.

To enable security, use the :code:bt security <level> command. For levels requiring authentication (level 3 and above), you must first set the authentication method. To do it, you can use the :code:bt auth all command. After that, when you will set the security level, you will be asked to confirm the passkey on both devices. On the shell side, do it with the command :code:bt auth-passkey-confirm.

Pairing

Enabling authentication requires the devices to be bondable. By default the shell is bondable. You can make the shell not bondable using :code:bt bondable off. You can list all the devices you are paired with using the command :code:bt bonds.

The maximum number of paired devices is set using :kconfig:option:CONFIG_BT_MAX_PAIRED. You can remove a paired device using :code:bt clear <address: XX:XX:XX:XX:XX:XX> <type: (public|random)> or remove all paired devices with the command :code:bt clear all.