Программирование
On-line приложения
Почитать
Web-сервер Apache
Печать и форматирование
MySQL
Разные рецепты
Сборка/установка
Справки
Философия
Мой опыт
Скачать
Программы на Tcl/Tk (GUI)
Программы на Python/Tk (GUI)
Программы (CLI)
Help
Хобби
Фракталы
on-line
Язык для рисования фракталов
Гиперкуб
Теория относительности
Ампуллярии
Преподавание
Студенту/абитуриенту
Мой опыт
Автора!

FreeBSD и 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

Если устройств много, то проще всего поступить так:

  • выключить ваше
  • получить список устройств
  • включить ваше
  • получить новый список
  • сравнить списки и «вычислить» как тут ваше

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

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 (хотя бы первое время).

Эта страница набрала не малую популярность, её посещает множество людей, поэтому я решил провести небольшое исследование. Если у вас есть комментарий, если вы сочли полученную информацию полезной, не полной, или вообще бесполезной, вы можете высказать своё мнение, пожелания, дополнения.

Если вы ожидаете получить от меня ответ или разъяснение, пожалуйста укажите e-mail, ICQ или другую контактную информацию.
Ваше сообщение не появится на странице, а просто отправится мне.

© 1999 − 2008 Мичурин Алексей — http://www.michurin.com.ru/