.. include:: /keyword.rst ===== BlueZ ===== .. contents:: Sections :local: :depth: 2 .. toctree:: :hidden: -------------------------------- This chapter covers the BlueZ stack on |IOT-YOCTO| and its common instructions. The Bluetooth stack depends on the module in use. BlueZ is compatible with the MT7921 module and other 3rd party modules support the Linux standard API. |IOT-YOCTO| currently supports GATT, HID, and HoGP profiles which are tested. While other profiles may be supported, MediaTek has not conducted full function tests for other profiles. However, you can still try the available commands for these profiles http://www.bluez.org/profiles. You can also read BlueZ how-to from other Linux distributions, like https://ubuntu.com/core/docs/bluez/how-to -------------------------------- Bluetooth service ================= Ensure that ``bluetooth.service`` and ``bluetoothd`` are running ---------------------------------------------------------------- First, make sure ``bluetooth.service`` and ``bluetoothd`` is running. Check ``bluetooth.service`` by ``systemctl``. .. prompt:: bash systemctl status bluetooth.service Check ``bluetoothd`` by ``ps``. .. prompt:: bash ps -aux | grep bluetoothd You should see 2 output lines correspond to each command respectively: .. code:: Active: active (running) .. code:: root 329 0.0 0.1 6952 4144 ? Ss 10:44 0:00 /usr/libexec/bluetooth/bluetoothd If not, launch ``bluetooth.service`` when you see the following output: The following output means ``bluetooth.service`` has been stopped. .. code:: * bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled; vendor pr> Active: inactive (dead) Docs: man:bluetoothd(8) Use ``systemctl`` to enable ``bluetooth.service``. .. prompt:: bash systemctl enable bluetooth.service ``Systemctl`` should register ``dbus-org.bluez.service`` and ``bluetooth.service`` to ``systemd`` and here's the output. .. code:: Created symlink /etc/systemd/system/dbus-org.bluez.service -> /lib/systemd/system/bluetooth.service. Created symlink /etc/systemd/system/bluetooth.target.wants/bluetooth.service -> /lib/systemd/system/bluetooth.service. Then, don't forget use ``systemctl`` to start ``bluetooth.service``, and then check if it is running again. .. prompt:: bash systemctl start bluetooth.service systemctl status bluetooth.service Make Sure the `hciX` Controller Exists -------------------------------------- Use ``hciconfig`` to check if the Bluetooth controller exists. .. prompt:: bash hciconfig A valid ``BD Address`` (MAC address of the Bluetooth controller) should be existed as the output instead of value ``00:00:00:00:00:00``. .. note:: The **Bus** type of `hciX` will be different depends on the module and the platform are used. It could be **SDIO** or **USB** usually. .. code:: hci0: Type: Primary Bus: USB BD Address: 90:E8:68:D4:39:84 ACL MTU: 1021:6 SCO MTU: 244:4 DOWN RX bytes:14464 acl:0 sco:0 events:1167 errors:0 TX bytes:293798 acl:0 sco:0 commands:1167 errors:0 -------------------------------- Prepare test application for paired phone ========================================= Install the ``nRF Connect for Mobile`` application on your Android phone or iPhone. Please note that the configuration and usage may differ between these two operating systems. Basic operation =============== Scan some advertising Bluetooth device nearby --------------------------------------------- Bluetooth device will be shown after ``scan on``. Bluetooth device will not be shown after ``scan off``. Start ``bluetoothctl`` to control the Bluetooth interface interactively. .. prompt:: bash bluetoothctl ``bluetoothctl`` will report the controller if there existed one. .. code:: text Agent registered [CHG] Controller 90:E8:68:D4:39:84 Pairable: yes You'll also find the prompt has been changed to ``[bluetooth]#``, which means we are under the interactive interface and menu in ``bluetoothctl``. .. prompt:: bash [bluetooth]# (waiting for bluetooth commands) Before using Bluetooth, we need to power on the device. .. prompt:: bash [bluetooth]# power on If it is success, you'll see the valid BD's address in log with message ``Powered: yes``. The Bluetooth controller is able to scan the neighbor devices now. Put the Bluetooth speaker into pairing mode, then simply run: .. prompt:: bash [bluetooth]# scan on Enable advertising on your device to make it discoverable during Bluetooth scanning ----------------------------------------------------------------------------------- Start ``bluetoothctl`` to control the Bluetooth interface interactively. .. prompt:: bash bluetoothctl ``bluetoothctl`` will report the controller if there existed one. .. code:: text Agent registered [CHG] Controller 90:E8:68:D4:39:84 Pairable: yes You'll also find the prompt has been changed to ``[bluetooth]#``, which means we are under the interactive interface and menu in ``bluetoothctl``. .. prompt:: bash [bluetooth]# menu advertise You'll enter ``advertise`` menu and device will show available commands. .. prompt:: bash [bluetooth]# name bluetoothAdv back Set the advertise name of your device. Then leave ``advertise`` menu. back to menu ``main``. .. prompt:: bash [bluetooth]# advertise peripheral The device will advertise itself by Bluetooth. You'll see the result as follows. .. code:: text [CHG] Controller 2C:3B:70:EB:14:82 SupportedInstances: 0x13 (19) [CHG] Controller 2C:3B:70:EB:14:82 ActiveInstances: 0x01 (1) Advertising object registered Tx Power: off LocalName: bluetoothdAdv Appearance: off Discoverable: on Now launch the ``nRF Connect for Mobile`` on your phone, select ``SCANNER`` and then clock ``scan``, You'll see the phone with name ``bluetoothAdv`` will appear on your phone. -------------------------------- HID and HOGP ============ Initiate connect to HID/HOGP device, and check data-input --------------------------------------------------------- Start ``bluetoothctl`` to control the Bluetooth interface interactively. .. prompt:: bash bluetoothctl ``bluetoothctl`` will report the controller if there existed one. .. code:: text Agent registered [CHG] Controller 90:E8:68:D4:39:84 Pairable: yes You'll also find the prompt has been changed to ``[bluetooth]#``, which means we are under the interactive interface and menu in ``bluetoothctl``. .. prompt:: bash [bluetooth]# (waiting for bluetooth commands) Before using Bluetooth, we need to power on the device. .. prompt:: bash [bluetooth]# power on If it is success, you'll see the valid BD's address in log with message ``Powered: yes``. The Bluetooth controller is able to scan the neighbor devices now. Put the Bluetooth speaker into pairing mode, then simply run: .. prompt:: bash [bluetooth]# scan on .. prompt:: bash [bluetooth]# pair xx:xx:xx:xx:xx connect xx:xx:xx:xx:xx exit Pair and connect EVK with the HID/HOGP device, while ``xx:xx:xx:xx:xx`` is the address of HID/HOGP Device. After the device has been connected, leave ``bluetoothctl``. .. prompt:: bash cd /dev/input evtest eventX Check every `eventX` (`event0`, `event1`...) from the HID or HOGP Device. Initiate disconnect & unpair to HID/HOGP device ----------------------------------------------- If you has exited the ``bluetootctl``, please execute the ``bluetoothctl`` again. .. prompt:: bash [bluetooth]# devices Command ``devices`` will show the Address of connected device. .. prompt:: bash [bluetooth]# disconnect xx:xx:xx:xx:xx (Address Of HID/HOGP Device) remove xx:xx:xx:xx:xx (Address Of HID/HOGP Device) Simply ``disconnet`` and ``remove`` the HID/HOGP device, while ``xx:xx:xx:xx:xx`` is the address of HID/HOGP Device. -------------------------------- GATT ==== Initiate connect to GATT device, and check data-input ----------------------------------------------------- Start ``bluetoothctl`` to control the Bluetooth interface interactively. .. prompt:: bash bluetoothctl ``bluetoothctl`` will report the controller if there existed one. .. code:: text Agent registered [CHG] Controller 90:E8:68:D4:39:84 Pairable: yes You'll also find the prompt has been changed to ``[bluetooth]#``, which means we are under the interactive interface and menu in ``bluetoothctl``. .. prompt:: bash [bluetooth]# (waiting for bluetooth commands) Before using Bluetooth, we need to power on the device. .. prompt:: bash [bluetooth]# power on If it is success, you'll see the valid BD's address in log with message `Powered: yes`. The Bluetooth controller is able to scan the neighbor devices now. Put the Bluetooth speaker into pairing mode, then simply run: .. prompt:: bash [bluetooth]# scan on Start Advertise --------------- After completing the following procedures, the remote device will be able to discover the advertisement named ``bluetoothAdv``. Before you begin, ensure that you have a smartphone with the ``nRFConnect`` application installed. For Android phones, use the ``nRFConnect.apk`` application. For iPhones, use the ``nRFConnect`` application.. On the Genio platforms, enter the ``advertise menu`` to set the ``advertise name`` for the Genio EVK. We set ``bluetoothAdv`` for the Genio platform. On Genio platform: .. prompt:: bash [bluetooth]# menu advertise name bluetoothAdv back advertise peripheral On smartphone: .. code:: text launch nRFConnect application select "SACNNER" click "scan" Genio platform with name ``bluetoothAdv`` should appear on smartphone. Set Advertisement Data for Device --------------------------------- On the Genio platforms, enter the ``advertise menu`` to set the ``advertise data`` for the Genio EVK. The following example should be available on smartphone: 1. uuids: ``0x181C,0x2a8a`` 2. service: ``UUID:2a90 Data: 0x55`` 3. data: ``(0x33): 44`` 4. tx-power: ``TxPower Level: XX dBm`` On Genio platform: .. prompt:: bash [bluetooth]# menu advertise uuids 0000181c-0000-1000-8000-00805f9b34fb 00002a8a-0000-1000-8000-00805f9b34fb service 00002a90-0000-1000-8000-00805f9b34fb 0x55 data 0x33 0x44 tx-power on On smartphone: .. code:: text launch nRFConnect application select "SACNNER" click "scan" find & click the "bluetoothdAdv" check advertised data Connect and Disconnect with GATT server --------------------------------------- To prepare testing environment on your smartphone, follow these steps. On smartphone (Preparation): .. code:: text Launch the nRFConnect app and start a connectable advertisement. 1. Launch nRFConnect application. 2. Select "ADVERTISER" 3. If you haven't created an advertiser before, select "+" to add one. If you have, skip this step. Configure the advertiser: 1.a Select "Display name" and input a name. 1.b Select "ADD RECORD" and then "Complete Local Name". This will be the advertisement name. 1.c Enable/Select "Connectable". 1.d Confirm by selecting "OK". 1.f Select the "Pen Symbol" in the upper right corner, input an easily recognizable name, and select "RENAME". This step changes the "Complete Local Name" into an easily recognizable broadcast name. 4. Select the "adv open button", begain to start adv On Genio platform: .. note:: The ``Address`` from the command line prompt needs to be formatted as ``5c:68:2e:3f:48:27``. If you cannot locate the device, use the devices command to find it. Please note that the format of the ``address`` in the command line prompt (e.g., ``5c-68-2e-3f-48-27``) should be changed to ``5c:68:2e:3f:48:27``. .. prompt:: bash [bluetooth]# scan on pair Address On smartphone: .. code:: text Click the "PAIR & CONNECTR " in phone, then click "PAIR". On Genio platform, input "yes" to agree. .. prompt:: bash [bluetooth]# yes On Genio platform, enter the ``advertise menu`` and show device's address. .. prompt:: bash [bluetooth]# menu gatt list-attributes back devices disconnect Address remove Address After executing the ``pair address`` command, the console prompt name will be updated to reflect the device's name. Once the ``list-attributes address`` command is run, the GATT service attribute list will be displayed. The console prompt name will revert back to ``bluetooth`` after the ``disconnect address`` command is executed. Read Data from GATT Server -------------------------- To prepare testing environment on your smartphone, follow these steps. On smartphone (Preparation): .. code:: text Configure the GATT service in the nRF app. If this has already been done, skip this step. 1. Launch nRFConnect application. 2. Select "Ξ". 3. Choose "Configure GATT server". 4. Click on "ADD SERVICE". If there is no "ADD SERVICE" option, select the "Triangle", then click on "+" to add a service. To configure the service: 1. Click on "ADD SERVICE". 2. Select "Select server configuration", then choose "Custom service". 3. Fill in the "Name" (e.g., Myservice1) and "UUID" (e.g., 1234, must be 4 digits), then click "OK". 4. Click on "Myservice1", then select "ADD CHARACTERISTIC". 5. Fill in the "Name" (e.g., Myservice1-char1), "UUID" (e.g., 1235), select all options for Properties and Permissions, select and fill in the "Text" for Initial value (e.g., Myservice3-char1 say hello!!), then click "OK". 6. Click on "ADD DESCRIPTOR". 7. Fill in the "Name" (e.g., Myservice1-char1-des1), "UUID" (e.g., 1236), select all options for Permissions, select and fill in the "Text" for Initial value (e.g., Myservice1-char1-des1 say hello!!), then click "OK". (If you want to configure more services/characteristics/descriptors, please repeat the above steps.) On Genio platform: Start a connectable advertisement. Please refer to section `Start Advertise` in this chapter for more details. After this step has been completed, execute the following steps. 1. Navigate to the ``gatt`` menu. 2. List the attributes using the ``list-attributes`` command. 3. Select the attribute using the ``select-attribute uuid`` command. Use the characteristic UUID (e.g., ``xxxx1235-xxxx-xxxx-xxxxx-xxxxxxxxxxx``) or descriptor UUID (e.g., ``xxxx1235-xxxx-xxxx-xxxxx-xxxxxxxxxxx``) that you created. 4. Operate the characteristic or descriptor that you created. 5. Use the ``attribute-info`` command to display the permissions. The characteristic or descriptor must support ``read`` to be readable by us. Since all permissions were selected when we created it, the characteristic or descriptor is readable. If the required permissions were not selected when creating it, you would need to add the corresponding permissions in the service editor. 6. Use the ``read 0`` command to read the attribute. '0' is the offset. .. prompt:: bash [bluetooth]# menu gatt list-attributes select-attribute UUID attribute-info read 0 .. note:: Please note that the characteristic or descriptor must have 'read' permission to be readable. When we created the characteristic or descriptor, we selected all permissions, which includes 'read'. Therefore, it is readable. If the required permissions were not selected during creation, you would need to add the corresponding permissions in the service editor. -------------------------------- Pair a Bluetooth Speaker then Play Sound ======================================== Bluetooth software stack in ``rity-demo-image`` supports ``hciconfig`` tool and **BlueZ** stack. Bluetooth service is registered as a ``systemd`` service. We cannot make Bluetooth connections without these userspace services. Let's check if the Bluetooth service is running in the beginning. Create a New User Account ------------------------- We could use ``pulseaudio``, ``pactl``, and ``paplay`` to play a wave sound to a paired Bluetooth speaker. However, a non-root user account is required for accessing these tools. Please follow the following steps to create a non-root user.. First, add a new user. .. prompt:: bash useradd mtk Assign ``/run/user/0/`` to the new user. .. prompt:: bash chown -R mtk /run/user/0/ Switch to the user account ``mtk``. .. prompt:: bash su mtk Pair a Bluetooth Speaker ------------------------ Start ``bluetoothctl`` to control the Bluetooth interface interactively. .. prompt:: bash bluetoothctl ``bluetoothctl`` will report the controller if there existed one. .. code:: text Agent registered [CHG] Controller 90:E8:68:D4:39:84 Pairable: yes You'll also find the prompt has been changed to ``[bluetooth]#``, which means we are under the interactive interface and menu in ``bluetoothctl``. .. prompt:: bash [bluetooth]# (waiting for bluetooth commands) Before using Bluetooth, we need to power on the device. .. prompt:: bash [bluetooth]# power on If it is success, you'll see the valid BD's address in log with message ``Powered: yes``. The Bluetooth controller is able to scan the neighbor devices now. Put the Bluetooth speaker into pairing mode, then simply run: .. prompt:: bash [bluetooth]# scan on ``bluetoothctl`` should dumps the BD address of each neighbor Bluetooth device. Please wait until the BD address of the Bluetooth speaker appeared (scanned by i350-EVK). For example, if the ```` of the speaker is ``FC:58:FA:34:46:06``: .. code:: text [NEW] Device FC:58:FA:34:46:06 AXLOIE Mega After the speaker has been scanned by ``bluetoothctl``, it should be trusted before the connection. .. prompt:: bash [bluetooth]#0 trust The device should be trusted by i350-EVK immediately. .. code:: text Changing trust succeeded. Finally, we can pair the speaker with i350-EVK. .. prompt:: bash [bluetooth]# pair After a while, it should be paired successfully. Sometimes you need to repeat and enter the key for pairing, or, simply type **yes** in interactive interface. .. code:: text [CHG] Device Paired: yes Pairing successful After the devices has been paired, we could exit ``bluetoothctl`` and prepare audio tools for playing sound. .. prompt:: bash [bluetooth]# exit Play Sound ---------- If the previous steps worked fine, ``pulseaudio`` could be run as a daemon for dealing with audio data. Launch ``pulseaudio`` in daemon mode. Note: Please run as the user ``mtk``. .. prompt:: bash pulseaudio -D --exit-idle-time -1 Now, we connect the Bluetooth device. .. prompt:: bash bluetoothctl connect Wait for a while, it should be connected successfully. .. code:: text [CHG] Device FC:58:FA:34:46:06 Connected: yes Connection successful Use ``pactl`` to list all BlueZ `a2dp` sink. .. prompt:: bash pactl list sinks | grep Name You'll find a line in outputs as below. .. code:: text Name: bluez_sink.FC_58_FA_34_46_06.a2dp_sink Finally, the music could be played to the Bluetooth speaker. .. prompt:: bash paplay /usr/share/sounds/alsa/Front_Right.wav -d You can hear voice **Front Right** form the connected speaker. -------------------------------- Turn off Bluetooth Service ========================== If you don't need Bluetooth and want to turn it off, simply run following command. .. prompt:: bash systemctl disable bluetooth.service Then the logs show as below. .. code:: text Removed /etc/systemd/system/dbus-org.bluez.service. Removed /etc/systemd/system/bluetooth.target.wants/bluetooth.service. It deregisters the ``dbus-org.bluez.service`` and ``bluetooth.service`` from ``systemd``. If you tried to use ``bluetoothctl`` after they've been deregistered, ``bluetoothctl`` will keep waiting for ``bluetoothd`` to be ready. It show the Bluetooth service has been turned off. -------------------------------- Reference Boards ================ Genio platforms support combo modules that provide both WIFI and Bluetooth functionalities. For hardware installation, please refer to the section on wireless installation. The installation method usage, performance, and software of Bluetooth may vary depending on the platform and module used. Please refer to the corresponding documentation for more information on these differences. - :doc:`Genio 1200-EVK Wireless Installation `. - :doc:`Genio 700-EVK Wireless Installation `.