воскресенье, 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

Комментариев нет:

Отправить комментарий