Показаны сообщения с ярлыком bluetooth. Показать все сообщения
Показаны сообщения с ярлыком bluetooth. Показать все сообщения

суббота, 27 января 2018 г.

Ubuntu: подключаем bluetooth-колонку

В общем, обзавёлся я bluetooth-колонкой. Ну захотелось засыпать под приятную музыку с ютуба, а компьютер стоит в другой комнате. Не дырявить же из-за такого пустяка стены! Поэтому выбор пал на bluetooth. В DNS-е прикупил Sven PS-170BL и принялся её настраивать.

Тут, думаю, уместно пару слов уделить самой колонке. Этакий массивный брусок из неизвестного металла, приятный на ощупь. В качестве бонуса - FM-радио, сумевшее поймать пару хрипящих радиостанций, и заявленное время автономной работы 10 часов. Последнее, правда, проверить ещё не удосужился.

Итак, настройка. После предыдущих экспериментов в системе остались какие-то установленные пакеты (bluez, pulseaudio-module-bluetooth), так что доустанавливать ничего не пришлось. Запустил апплет blueman-applet, включил поиск устройств, тот нашел колонку, находящуюся в режиме bluetooth, и успешно подключился. Руководство пользователя к колонке предупреждало, что, возможно, потребуется ввести пароль 0000, но это не понадобилось. Кстати, пароль тут, похоже, неизменяемый, так что надо быть готовым к тому, что какой-нибудь шутник-сосед за стеной подключится и начнет транслировать всякие непристойности.

На этом настройка не закончилась. Командой pavucontrol вызвал регулятор громкости. В нём есть вкладка "Конфигурация". В этой вкладке отображаются всякие аудиоустройства. Надо найти свой пункт "Sven PS-170BL" и выбрать профиль "Воспроизведение высокого качества (приемник A2DP)" (откуда он там взялся - это, конечно, интересный вопрос). Во вкладке "Устройства вывода" эту колонку можно сделать устройством вывода звука по умолчанию, но моя задача заключалась не в этом.
Задача у меня стояла сделать так, чтобы часть приложений пищала через интегрированную на материнку звуковую карту, а другая часть - через колонку. Сделать это оказалось просто. При запуске приложения, пытающегося вывести звук (например, firefox или mpg123), это приложение появляется в списке во вкладке "Проигрывание", и для него можно выбрать требуемое устройство вывода.

Кроме того, для mpg123 можно вообще обойтись CLI. Команда
pacmd list-sinks
выдаёт некий список примерно такого вида:
2 sink(s) available.
  * index: 0
        name: <alsa_output.pci-0000_00_07.0.analog-stereo>
        driver: <module-alsa-card.c>
        ....
        ....
    index: 7
        name: <bluez_sink.30_41_30_FA_95_57>
        driver: <module-bluez5-device.c>
        ....
        ....
        module: 33
        properties:
                bluetooth.protocol = "a2dp_sink"
                device.description = "SVEN PS-170BL"
                device.string = "30:41:30:FA:95:57"
                device.api = "bluez"
                device.class = "sound"
                device.bus = "bluetooth"
                device.form_factor = "hands-free"
                bluez.path = "/org/bluez/hci0/dev_30_41_30_FA_95_57"
                bluez.class = "0x240408"
                bluez.alias = "SVEN PS-170BL"
                device.icon_name = "audio-handsfree-bluetooth"
                device.intended_roles = "phone"
        ports:
                handsfree-output: Хендс-фри (priority 0, latency offset 0 usec, available: yes)
                        properties:
    
        active port: 
В нём нас интересует одна строка: "name: <bluez_sink.30_41_30_FA_95_57>". В домашнем каталоге создаём файл ~/.asoundrc с таким содержимым:
pcm.bluetooth {
        type pulse
        device "bluez_sink.30_41_30_FA_95_57"
}
Теперь можно вызывать mpg123 такой командой:
mpg123 -o alsa -a bluetooth мой_файл.mp3
и звук пойдёт через колонку.

Литература
https://wiki.archlinux.org/index.php/Bluetooth_headset_(Русский)
https://wiki.archlinux.org/index.php/PulseAudio_(Русский)
https://askubuntu.com/questions/609292/different-applications-different-sound-output-devices
https://askubuntu.com/questions/14077/how-can-i-change-the-default-audio-device-from-command-line
https://wiki.debian.org/Bluetooth/Alsa

воскресенье, 19 февраля 2017 г.

Philips Xenium E181: связь через Bluetooth с Linux

Всё началось, как обычно, с пустяка. Как я уже когда-то говорил, с незапамятных времён мне верой и правдой служил замечательный сотовый телефон Samsung SGH-X100. Это была удобная звонилка, компактная, с приятным интерфейсом и прикольным белым медведем на заставке. Конечно не без недостатков - на ней как-то странно выглядели кириллические ответы на запрос баланса, MMS-сообщения не открывались и т.д. Да и с компьютером я её не успел подружить: сначала было как-то не нужно, а когда стало нужно, найти соответствующий USB-кабель оказалось проблематично.

Но всему приходит конец. В последнее время сотик постарел - испортилась пластмассовая защелка аккумулятора - и стал отключаться в самый неподходящий момент. Поэтому было принято трудное решение: купить другую звонилку. Выбор пал на Philips Xenium E181. Во-первых, какие-то зашкаливающие показатели аптайма, и, во-вторых, конечно, цена.

Сам телефон прост и безыскусен. Скорее даже это аккумулятор с возможностью позвонить. Умеет заряжаться от компьютера через micro-USB. Умеет работать с двумя симками (мне это не актуально). Есть слот для micro-SD (карту памяти надо покупать отдельно). Есть полноразмерный female USB-порт - для подзарядки(!) других устройств (открытый, могли бы положить заглушку, а то в кармане в него лезет всякий мусор, пришлось заказывать резиновую затычку на алиэкспрессе). Есть фотокамера 0.3 Mpx (качество снимков, разумеется, никакое). Есть радио. Есть фонарик (вот это полезно). Есть диктофон. Что ещё надо для счастья!

Как выяснилось, для счастья надо, чтобы была возможность обмениваться файлами с этим чудом инженерной мысли. Если подключить телефон по USB, он предлагает перейти в режим накопительного устройства, но моя убунта 15.10 его в качестве флэшки, увы, не воспринимает. Поэтому возникла надежда наладить файловый обмен через Bluetooth. С этой целью с дальней полки был вытащен, очищен от пыли и воткнут в свободный порт компьютера некий Bluetooth-адаптер. Линукс его, к счастью, без проблем подхватил, о чем свидетельствует вывод команды lsusb:
Bus 003 Device 002: ID 1310:0001 Roper Class 1 Bluetooth Dongle
Дальше началась терра инкогнита.

Оказывается, для работы с блютусом под линуксом используется некий программный продукт bluez и куча утилит, нещадно его эксплуатирующих. В частности, для настройки подключения к устройствам Bluetooth можно использовать утилиту bluetoothctl. Выглядит это так:
$ sudo bluetoothctl
[NEW] Controller 00:0B:0D:09:04:DF BlueZ 5.40 [default]

(включили блютус)
[bluetooth]# power on
Changing power on succeeded

(включили сканирование окружающего пространства на предмет наличия других блютус-устройств)
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:0B:0D:09:04:DF Discovering: yes
[NEW] Device 89:61:8F:C0:48:BA Philips E181

(посмотрели информацию о своём адаптере)
[bluetooth]# show
Controller 00:0B:0D:09:04:DF
 Name: BlueZ 5.40
 Alias: BlueZ 5.40
 Class: 0x000104
 Powered: yes
 Discoverable: yes
 Pairable: yes
 UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
 UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
 UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
 UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
 UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
 Modalias: usb:v1D6Bp0246d0528
 Discovering: no

(посмотрели информацию о найденном телефоне)
[bluetooth]# info 89:61:8F:C0:48:BA
Device 89:61:8F:C0:48:BA
 Name: Philips E181
 Alias: Philips E181
 Class: 0x5a0204
 Icon: phone
 Paired: no
 Trusted: no
 Blocked: no
 Connected: no
 LegacyPairing: yes

(сказали, что мы этому устройству доверяем)
[bluetooth]# trust 89:61:8F:C0:48:BA
[CHG] Device 89:61:8F:C0:48:BA Trusted: yes

(попытались сделать сопряжение и обломились)
[bluetooth]# pair 89:61:8F:C0:48:BA
Attempting to pair with 80:61:8F:C0:48:BA
[CHG] Device 89:61:8F:C0:48:BA Connected: yes
Failed to pair: org.bluez.Error.AuthenticationFailed
[CHG] Device 89:61:8F:C0:48:BA Connected: no

(оказывается, надо еще зарегистрировать некого агента)
[bluetooth]# agent on
Agent registered

(попытались сделать сопряжение, на этот раз успешно)
[bluetooth]# pair 89:61:8F:C0:48:BA 
Attempting to pair with 89:61:8F:C0:48:BA
[CHG] Device 89:61:8F:C0:48:BA Connected: yes
Request PIN code
[agent] Enter PIN code: 0000
[CHG] Device 89:61:8F:C0:48:BA Modalias: bluetooth:v0046p0802d0903
[CHG] Device 89:61:8F:C0:48:BA UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device 89:61:8F:C0:48:BA UUIDs: 00001112-0000-1000-8000-00805f9b34fb
[CHG] Device 89:61:8F:C0:48:BA UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 89:61:8F:C0:48:BA UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 89:61:8F:C0:48:BA Paired: yes
Pairing successful
[CHG] Device 89:61:8F:C0:48:BA Connected: no
[CHG] Device 89:61:8F:C0:48:BA Connected: yes
[CHG] Device 89:61:8F:C0:48:BA Connected: no

(На этом счастье закончилось)
[bluetooth]# connect 89:61:8F:C0:48:BA 
Attempting to connect to 89:61:8F:C0:48:BA
[CHG] Device 89:61:8F:C0:48:BA Connected: yes
Failed to connect: org.bluez.Error.NotAvailable
[CHG] Device 89:61:8F:C0:48:BA Connected: no

(заплакали и вышли)
[bluetooth]# exit
В общем, сопрячь телефон с компьютером удалось, а вот наладить постоянный коннект - нет.

Однако, оказалось, не всё потеряно. Гугль посоветовал выполнить такую команду:
$ sdptool browse 89:61:8F:C0:48:BA
Browsing 89:61:8F:C0:48:BA ...
Service Name: Voiceg ateway
Service RecHandle: 0x10001
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 2
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0105

Service Name: AUDIO Gateway
Service RecHandle: 0x10002
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0102

Service Name: OBEX Object Push
Service RecHandle: 0x10003
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 5
  "OBEX" (0x0008)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Среди этого нам интересен последний пункт, OBEX Object Push. Как видим, для передачи файлов нужно использовать канал 5.
Передачу эту на предварительно сопряженный через bluetoothctl телефон можно успешно осуществить следующей командой:
obexftp -b 89:61:8F:C0:48:BA -B 5 -p myfile.mp3 
Увы, на этом счастье изменило мне окончательно. Получить какой бы то ни было файл в CLI или даже просто просмотреть содержимое карты памяти сотика мне так и не удалось:
$ obexftp -b 89:61:8F:C0:48:BA -B 5 -l /
Connecting..\done
Receiving "/"... Sending ""...|failed: /
failed: /
The operation failed with return code 1
Disconnecting...failed: disconnect

Пришлось обратиться к GUI. В xubuntu нашлась некое приложение blueman-applet, которое, будучи запущенным,
во-первых, позволяет телефону находить компьютер и инициировать подключение, во-вторых, успешно держит коннект с телефоном, и, в-третьих, не менее успешно ловит файлы, отправляемые с этого телефона на компьютер. Единственная тонкость: оно не любит русские буквы в пути, по которому будет сохранять принятые файлы. Точнее, не оно, а питон 2.7, на котором оно написано. В модуле /usr/lib/python2.7/site-packages/blueman/plugins/applet/TransferService.py в методе _on_transfer_completed присутствует строка:
        if os.path.exists(os.path.join(dest_dir, filename)):
            ...
В слаквари перед ней есть костыль:
        # We get bytes from pygobject under python 2.7
        if hasattr(dest_dir, "upper",) and hasattr(dest_dir, "decode"):
            dest_dir = dest_dir.decode("UTF-8")

        if os.path.exists(os.path.join(dest_dir, filename)):
            ...
а в убунте нет, поэтому питон дохнет с ошибкой "Ordinal not in range". Правда, в слаквари с этой утилитой свои тонкости: она "из коробки" не работает - не хватает прав. Пришлось подправить файл /etc/dbus-1/system.d/bluetooth.conf, заменив в нем policy user="root" на policy group="wheel". Говорят, что это моветон, но пусть уж так, чем никак. В общем, может быть, когда-нибудь попробую сделать на том же питоне консольную программку с аналогичными полезными свойствами, но с более понятным жизненным циклом.

Остались за бортом этого краткого обзора некие загадочные и, судя по всему, полезные команды:
hcitool scan
hcitool dev
sudo rfcomm connect /dev/rfcomm0 89:61:8F:C0:48:BA <канал>
но что они означают и как могут облегчить всем жизнь, я вникать пока не стал.

Литература:

https://wiki.archlinux.org/index.php/Bluetooth
https://www.garron.me/en/go2linux/how-transfer-files-bluetooth-linux.html
https://help.ubuntu.com/community/BluetoothSetup