FreeBSD и bluetooth : приём и передача файлов через USB-bluetooth-адаптер


Про работу с bluetooth-устройствами под FreeBSD сказано очень много… я бы сказал: очень много лишнего. На самом деле всё гораздо проще, чем пишут в блогах и даже в handbook. Я думаю, это связано с тем, что информация устаревает. Я опишу как работать с USB-bluetooth адаптером под FreeBSD 6.1, возможно на более старых версиях этих действий будет недостаточно.

Несколько слов о USB под FreeBSD
FreeBSD очень капризна при работе с USB-устройствами. Больше всего она не любит, когда они неожиданно исчезают. Поэтому я буду рассказывать обо всём очень подробно, на каждом шагу проверяя, всё ли прошло правильно. От этого рассказ получается длинным, но на самом деле он описывает на много меньше действий, чем другие, известные мне, руководства. Не пугайтесь.

Зачем мне нужен bluetooth
Я использую USB-bluetooth адаптер для связи со своим сотовым телефоном. Пользуюсь я этой связью эпизодически, поэтому не хочу ради неё засорять систему лишними демонами и софтом. Я подключаюсь, переливаю файлы и отключаюсь, такую работу я и опишу, но если вам нужно постоянное подключение, вы можете легко адаптировать мои примеры под свои задачи.

Подключение адаптера
Подгружаем модули ядра (по необходимости):

# эти два модуля автоматически загружает команда
# ngctl; даже, если их загрузка у вас нигде не прописана,
# возможно, они уже загружены ею
kldload netgraph
kldload ng_socket

# модуль устройства USB-bluetooth
kldload ng_ubt

# модули bluetooth
kldload ng_bluetooth
kldload ng_hci
kldload ng_l2cap
kldload ng_btsocket

Обратите внимание, что некоторые из этих модулей при загрузке сами загружают недостающие. Поэтому, если вы будете загружать их в другом порядке, то обнаружите, что какие-то уже загружены.

Вот соответствующий фрагмент листинга kldstat:


9 1 0xcc68f000 7000 ng_ubt.ko
10 5 0xcc761000 a000 netgraph.ko
11 4 0xcc696000 2000 ng_bluetooth.ko
12 1 0xcc77c000 c000 ng_hci.ko
13 1 0xcc869000 e000 ng_l2cap.ko
14 1 0xccb66000 17000 ng_btsocket.ko
15 1 0xcc740000 4000 ng_socket.ko

Модуль ng_btsocket при загрузке создаёт несколько netgraph-нодов. Вот, что, примерно, должна выдать команда ngctl list:

There are 4 total nodes:
Name: ngctl649 Type: socket ID: 0000000a Num hooks: 0
Name: btsock_l2c Type: btsock_l2c ID: 00000009 Num hooks: 0
Name: btsock_l2c_raw Type: btsock_l2c_raw ID: 00000008 Num hooks: 0
Name: btsock_hci_raw Type: btsock_hci_raw ID: 00000007 Num hooks: 0

Теперь подключаем адаптер и смотрим на системную консоль или вывод dmesg. Если всё нормально, то вы должны увидеть что-то вроде этого:

ubt0: vendor 0x0a12 product 0x0001, rev 2.00/19.58, addr 2
ubt0: vendor 0x0a12 product 0x0001, rev 2.00/19.58, addr 2
ubt0: Interface 0 endpoints: interrupt=0x81, bulk-in=0x82, bulk-out=0x2
ubt0: Interface 1 (alt.config 5) endpoints: isoc-in=0x83, isoc-out=0x3;
wMaxPacketSize=49; nframes=6, buffer size=294

Таким образом, устройство подключено, как ubt0.

Запускаем стек
Если вы обладатель FreeBSD 6.1, то по этому пункту ничего делать не надо. Поясню.

В handbook и других источниках написано, что стек надо настраивать. Но во FreeBSD 6.1 стек настраивается автоматически. Проверить, что стек уже настроен можно командой

ngctl list

При включённом USB-bluetooth адаптере её вывод будет примерно таким:

There are 7 total nodes:
Name: ngctl94194 Type: socket ID: 00000083 Num hooks: 0
Name: ubt0l2cap Type: l2cap ID: 0000007d Num hooks: 3
Name: ubt0hci Type: hci ID: 00000079 Num hooks: 3
Name: ubt0 Type: ubt ID: 00000077 Num hooks: 1
Name: btsock_l2c Type: btsock_l2c ID: 00000004 Num hooks: 1
Name: btsock_l2c_raw Type: btsock_l2c_raw ID: 00000003 Num hooks: 1
Name: btsock_hci_raw Type: btsock_hci_raw ID: 00000002 Num hooks: 1

Обратите внимание на ноды ubt0l2cap, ubt0hci и ubt0. Они появились сразу после подключения устройства. Тогда же были созданы «крючки» (hooks в правой колонке).

Во FreeBSD 6.0 стек ещё требовал ручной настройки. Если вы подключили ваш адаптер, но в отчёте ngctl list видите меньше строк и в правой колонке только нули, то вам надо воспользоваться скриптом /usr/share/examples/netgraph/bluetooth/rc.bluetooth (как советует handbook). Однако, без надобности я бы не советовал его запускать. Если вы посмотрите внутрь этого скрипта, то сможете сами убедиться, что написано он несколько… небрежно. Он выполняет массу ненужных действий (пытается повторно загрузить модули, которые уже загружены и прочее), совершает странные действия (например, запускает сам себя, причём делает это не командой /bin/sh $0, а просто $0). Одним словом, этот скрипт не является полноценным, качественным средством, а лишь пример того, что следует сделать.

Запуск демона авторизации
Находим bluetooth-устройство

Сперва нам надо определить MAK-адрес нашего устройства. Просим адаптер поискать все доступные устройства:

hccontrol -n ubt0hci inquiry

Если устройств много, то проще всего поступить так:
• выключить ваше
• получить список устройств
• включить ваше
• получить новый список
• сравнить списки и «вычислить», какoe тут ваше

Запись о моём устройстве выглядит так:

Inquiry result #0
BD_ADDR: 00:18:af:36:fb:ce
Page Scan Rep. Mode: 0x1
Page Scan Period Mode: 0x2
Page Scan Mode: 00
Class: 50:02:04
Clock offset: 0x582a

Главное тут — адрес — 00:18:af:36:fb:ce.

Вы можете убедиться, что это именно ваше устройство, запросив явно его имя. Команда:

hccontrol -n ubt0hci remote_name_request 00:18:af:36:fb:ce

Ответ в моём случае:

BD_ADDR: 00:18:af:36:fb:ce
Name: SGH-X630-MICHURIN

Кстати, утилита hccontrol позволяет выполнить множество разных полезных действий. Например, вы можете дать вашему USB-адаптеру новое имя:

hccontrol -n ubt0hci change_local_name Michurin-PC

Убеждаемся, что связь есть

Теперь можно попинговать наше устройство:

l2ping -a 00:18:af:36:fb:ce -c 3

У меня результат выглядит так:

4 bytes from 00:18:af:36:fb:ce seq_no=1313822285 time=734.806 ms result=0
4 bytes from 00:18:af:36:fb:ce seq_no=1313822285 time=293.668 ms result=0
4 bytes from 00:18:af:36:fb:ce seq_no=1313822285 time=25.686 ms result=0

result=0 — это не страшно, так поступают большинство устройств.
Настраиваем демона PIN-авторизации

Чтобы устройства могли обменяться PIN-кодами при подключении, существует специальный демон hcsecd. Сперва создаём для него файл конфигурации примерно такого содержания:

device {
bdaddr 00:18:af:36:fb:ce;
name "BlueToothLink";
key nokey;
pin "12345";
}

Теперь для авторизации будет использоваться указанный PIN-код.
Запускаем демона PIN-авторизации

Можно настроить rc.conf так, чтобы демон hcsecd запускался при старте системы, но мне это не нужно, я запускаю демона на отдельной консоли в отладочном режиме, чтобы его можно было убить просто нажав Ctrl-C.

hcsecd -d -f ./hcsecd.conf

Теперь всё готово к работе.

Передача файлов
Программа obexapp

Для передачи файлов, вам нужно поставить программу obexapp. Её можно только собрать из портов:

cd /usr/ports/comms/obexapp
make
make install

Программа не большая, собирается быстро и без проблем. Из дополнительного требует только библиотеку openobex, которая тоже очень невелика.

Передача файлов через USB-bluetooth адаптер
Можно использовать только ключи командной строки. Например, чтобы передать файл используйте такую команду:

obexapp -c -a 00:18:af:36:fb:ce -C opush -n put 11-Zolotye_vode_Ganga.mp3

Подробности читайте в man obexapp. главным в этой команде является указание адреса устройства, протокола (opush) и команды (put).

Программа obexapp может работать и как интерактивный клиент (очень похоже на FTP-клиента командной строки). Вот пример сеанса работа:

~$ obexapp -a 00:18:af:36:fb:ce -C FTRN
obex> ls
Access Owner Group Size Modified Name
n/a n/a n/a n/a Photos/
n/a n/a n/a n/a DownLoaded Images/
n/a n/a n/a n/a Favorite Images/
n/a n/a n/a n/a Video clips/
n/a n/a n/a n/a DownLoaded Videos/
n/a n/a n/a n/a Favorite Videos/
n/a n/a n/a n/a Music/
n/a n/a n/a n/a Voice list/
n/a n/a n/a n/a Downloaded Sounds/
n/a n/a n/a n/a Favorite Sounds/
n/a n/a n/a n/a Other Files/
Success, response: OK, Success (0x20)
obex> cd Photos
Success, response: OK, Success (0x20)
obex> ls
Access Owner Group Size Modified Name
..
RWD n/a n/a 51722 07-Sep-07 11:14G SP_A0197.jpg
Success, response: OK, Success (0x20)
obex> get SP_A0197.jpg
Success, response: OK, Success (0x20)
obex>

Здесь я использовал протокол FTRN (протокол передачи файлов). Как видите, я получил список файлов в корне (команда ls), зашёл в директорию Photos, снова посмотрел список файлов и скачал фотографию с телефона а свою машину. Естественно, если вы знаете правильный путь к файлу на bluetooth-устройстве, то скачивать файлы можно и в неинтерактивном режиме, тут уж кому как удобно.

Отключение
Останавливаем hcsecd (в нашем случае — Ctrl-C).

Проверьте, нет ли открытых сокетов, командой btsockstat. Если она ничего не пишет, значит все сокеты закрыты и можно отключать адаптер.

Отключаем адаптер
В принципе можно и модули ядра выгрузить, но я бы не советовал лишний раз травмировать ядро.

Ненужные netgraph-ноды пропадут сами, когда вы отключите USB-bluetooth адаптер.

Возможные неполадки
Иногда obexapp не удаётся подключиться к устройству, возникают странные ошибки типа

OBEX_TransportConnect failed

Если до этого всё было нормально: модули загрузились, l2ping сработал…, то скорей всего дело в вашем телефоне. В нём уже есть запись для вашего USB-адаптера? Удалите её и заведите снова — это помогает.

Очень редко бывают ситуации, что ошибка

OBEX_TransportConnect failed

начинает появляться «на ровном месте»: всё работало, и вдруг перестало. В этом случае рекомендую остановить все bluetooth-приложения и выполнить команду

hccontrol -n ubt0hci reset

При этом, у большинства адаптеров гаснет индикатор.

Теперь вынимаем адаптер, вставляем его назад и снова запускаем hcsecd и obexapp. Всё должно заработать.

Компьютер как bluetooth-сервер
Чтобы можно было ходить с телефона (или другого bluetooth-устройства) на компьютер (просматривать файлы и папки, скачивать информацию), необходимо предпринять ещё один шаг. И так, с самого начала.

Настраиваем ядро, как и раньше. Запускаем hcsecd. Теперь запускаем ещё одного демона:

sdpd -d

(ключ -d — режим диагностики и отладки)

Теперь запускаем сервер:

obexapp -s -d -C 10 -r /root/BT

• опция -s — режим сервера
• опция -d — режим отладки
• опция -C 10 — канал
• опция -r путь — корень сервера, сюда вы будете попадать с другого bluetooth-устройства

Всё готово! Подключайтесь.

Обратите внимание, что все перечисленные утилиты имеют набор опций, управляющих уровнем безопасности. Раз уж вы решили дать доступ к своей машине, то позаботьтесь о безопасности.

Кроме того, если obexapp не может открыть сокет к sdpd, то завершается без каких-либо сообщений. Если obexapp молча отказывается работать, проверьте права или запускайте всё от пользователя root (хотя бы первое время).


Комментарии запрещены.




Статистика