Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for BLE passkey authentication #2607

Merged
merged 19 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 209 additions & 5 deletions components/ble_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ but merely manages connections to them for use by other components.
ESP32 BLE stack. If you wish to connect more devices, use additional
ESP32 boards.

This component does not (yet) support devices that require
security settings (eg connecting with a PIN).
This component supports devices that require a 6 digit PIN code
for authentication.

Currently, devices connected with the client cannot be
supported by other components based on :doc:`/components/esp32_ble_tracker`
Expand Down Expand Up @@ -53,6 +53,12 @@ Automations:
when the client connects to a device. See :ref:`ble_client-on_connect`.
- **on_disconnect** (*Optional*, :ref:`Automation <automation>`): An automation to perform
when the client disconnects from a device. See :ref:`ble_client-on_disconnect`.
- **on_passkey_request** (*Optional*, :ref:`Automation <automation>`): An automation to enter
the passkey required by the other BLE device. See :ref:`ble_client-on_passkey_request`.
- **on_passkey_notification** (*Optional*, :ref:`Automation <automation>`): An automation to
display the passkey to the user. See :ref:`ble_client-on_passkey_notification`.
- **on_numeric_comparison_request** (*Optional*, :ref:`Automation <automation>`): An automation to
compare the passkeys shown on the two BLE devices. See :ref:`ble_client-on_numeric_comparison_request`.

BLE Client Automation
---------------------
Expand Down Expand Up @@ -91,6 +97,64 @@ This automation is triggered when the client disconnects from a BLE device.
- lambda: |-
ESP_LOGD("ble_client_lambda", "Disconnected from BLE device");


.. _ble_client-on_passkey_request:

``on_passkey_request``
**********************

This automation is triggered when the BLE device requests a passkey for authentication.

.. code-block:: yaml

ble_client:
- mac_address: 11:22:33:44:55:66
id: ble_itag
on_passkey_request:
then:
- ble_client.passkey_reply:
id: ble_itag
passkey: 123456

.. _ble_client-on_passkey_notification:

``on_passkey_notification``
***************************

This automation is triggered when a passkey is received from the BLE device.

.. code-block:: yaml

ble_client:
- mac_address: 11:22:33:44:55:66
id: ble_itag
on_passkey_notification:
then:
- logger.log:
format: "Enter this passkey on your BLE device: %06d"
args: [ passkey ]

.. _ble_client-on_numeric_comparison_request:

``on_numeric_comparison_request``
*********************************

This automation is triggered when a numeric comparison is requested by the BLE device.

.. code-block:: yaml

ble_client:
- mac_address: 11:22:33:44:55:66
id: ble_itag
on_numeric_comparison_request:
then:
- logger.log:
format: "Compare this passkey with the one on your BLE device: %06d"
args: [ passkey ]
- ble_client.numeric_comparison_reply:
id: ble_itag
accept: True

.. _ble_client-ble_write_action:

``ble_client.ble_write`` Action
Expand Down Expand Up @@ -133,6 +197,75 @@ Configuration variables:
- **characteristic_uuid** (**Required**, UUID): UUID of the service's characteristic to write to.
- **value** (**Required**, Array of bytes or :ref:`lambda <config-lambda>`): The value to be written.

.. _ble_client-passkey_reply_action:

``ble_client.passkey_reply`` Action
-----------------------------------

This action triggers an authentication attempt using the specified ``passkey``.

Example usage:

.. code-block:: yaml

on_...:
then:
- ble_client.passkey_reply:
id: my_ble_client
passkey: 123456

Configuration variables:

- **id** (**Required**, :ref:`config-id`): ID of the associated BLE client.
- **passkey** (**Required**, int): The 6-digit passkey.

.. _ble_client-numeric_comparison_reply_action:

``ble_client.numeric_comparison_reply`` Action
----------------------------------------------

This action triggers an authentication attempt after a numeric comparison.

Example usage:

.. code-block:: yaml

on_...:
then:
- ble_client.numeric_comparison_reply:
id: my_ble_client
accept: True

Configuration variables:

- **id** (**Required**, :ref:`config-id`): ID of the associated BLE client.
- **accept** (**Required**, boolean): Should be ``true`` if the passkeys
displayed on both BLE devices are matching.

.. _ble_client-remove_bond_action:

``ble_client.remove_bond`` Action
----------------------------------------------

This action removes a device from the security database and manages
unpairing.

Example usage:

.. code-block:: yaml

ble_client:
- mac_address: 11:22:33:44:55:66
id: my_ble_client
on_connect:
then:
- ble_client.remove_bond:
id: my_ble_client

Configuration variables:

- **id** (**Required**, :ref:`config-id`): ID of the associated BLE client.

BLE Overview
------------
This section gives a brief overview of the Bluetooth LE architecture
Expand Down Expand Up @@ -186,9 +319,8 @@ characteristics and descriptors also provide a small 2-byte
Setting Up Devices
------------------

Whilst the component can connect to most BLE devices (that do not
require authentication/pin), useful functionality is only obtained
through dependent components, such as :doc:`/components/sensor/ble_client`.
Whilst the component can connect to most BLE devices, useful functionality
is only obtained through dependent components, such as :doc:`/components/sensor/ble_client`.
See the documentation for these components for details on setting up
specific devices.

Expand Down Expand Up @@ -247,6 +379,78 @@ The discovered services can then be used to enable and configure other
ESPHome components, for example Service UUID 0xFFE0 is used for iTag style
keychain button events, used by the :doc:`/components/sensor/ble_client` component.

Passkey examples
----------------

Secure connection with a fixed passkey:

.. code-block:: yaml

esp32_ble:
io_capability: keyboard_only

esp32_ble_tracker:

ble_client:
- mac_address: A4:C1:38:B1:CD:7F
id: pvvx_ble_display
on_passkey_request:
then:
- logger.log: "Authenticating with passkey"
- ble_client.passkey_reply:
id: pvvx_ble_display
passkey: 123456

Secure connection with a dynamically generated passkey:

.. code-block:: yaml

api:
services:
- service: passkey_reply
variables:
passkey: int
then:
- logger.log: "Authenticating with passkey"
- ble_client.passkey_reply:
id: my_ble_client
passkey: !lambda return passkey;
- service: numeric_comparison_reply
variables:
accept: bool
then:
- logger.log: "Authenticating with numeric comparison"
- ble_client.numeric_comparison_reply:
id: my_ble_client
accept: !lambda return accept;

esp32_ble:
io_capability: keyboard_display

esp32_ble_tracker:

ble_client:
- mac_address: AA:BB:CC:DD:EE:FF
id: my_ble_client
on_passkey_request:
then:
- logger.log: "Enter the passkey displayed on your BLE device"
- logger.log: " Go to https://my.home-assistant.io/redirect/developer_services/ and select passkey_reply"
on_passkey_notification:
then:
- logger.log:
format: "Enter this passkey on your BLE device: %06d"
args: [ passkey ]
on_numeric_comparison_request:
then:
- logger.log:
format: "Compare this passkey with the one on your BLE device: %06d"
args: [ passkey ]
- logger.log: " Go to https://my.home-assistant.io/redirect/developer_services/ and select numeric_comparison_reply"
on_connect:
then:
- logger.log: "Connected"

See Also
--------

Expand Down
11 changes: 10 additions & 1 deletion components/esp32_ble.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ can run.
# Example configuration

esp32_ble:
io_capability: keyboard_only

Configuration variables:
------------------------

No configuration variables.
- **io_capability** (*Optional*, enum): The IO capability of this ESP32, used for securely connecting to other BLE devices. Defaults to ``none``.

- ``none`` - No IO capability (Connections that require PIN code authentication will fail)
- ``keyboard_only`` - Only a keyboard to enter PIN codes (or a fixed PIN code)
- ``display_only`` - Only a display to show PIN codes
- ``keyboard_display`` - A keyboard and a display
- ``display_yes_no`` - A display to show PIN codes and buttons to confirm or deny the connection

See Also
--------
Expand Down