Ключевые слова:bluetooth, freebsd, driver, wireless, hardware, palm, ppp, modem, phone, (найти похожие документы)
From: Alex Samorukov <samm@os2.kiev.ua.>
Newsgroups: email
Date: Mon, 7 Nov 2005 14:31:37 +0000 (UTC)
Subject: Использование Bluetooth в FreeBSD
Отмазки
-------
Данная заметка не претендует на универсальность и совершенно не
заменяет чтение соответствующей главы руководства и манов
bluetooth(3), l2ping(8), hcsecd(8), sdpcontrol(8),
sdpd(8), ng_ubt(4), sdp(3), obexapp(1)). Цель заметки -
обобщить полученные в результате экспериментов результаты и собрать
все это в одном документе
Дано
Из Bluetooth устройств у меня имеется мобильник Siemens S55, Palm Zire
72s и безымянный Bluetooth USB адаптер (vendor 0x1131, product 0x1001)
купленный в ближайшей компьютерной лавке. Судя по данным
http://www.linux-usb.org/usb.ids им оказался Integrated System Solution Corp. KY-BT100
Bluetooth Adapter. ОС - FreeBSD 6-STABLE, впрочем, все описываемое
должно работать и в 5.xx.
Первоначальные настройки.
Bluetooth стек в FreeBSD реализован как нода netgraph(3) ng_ubt. Я
рекомендую использовать динамическую загрузку netgraph модулей вместо
компиляции в ядре. Для того, чтобы загрузить модуль Bluetooth наберите
до подключения устройства:
# kldload ng_ubt
Чтобы добавить данный драйвер в автозагрузку - добавте в
/boot/loader.conf строку
ng_ubt_load="YES"
После подключения устройства вы должны увидеть в логах и/или на
консоли строки такого вида:
ubt0: vendor 0x1131 product 0x1001, rev 1.10/3.73, addr 2
ubt0: vendor 0x1131 product 0x1001, rev 1.10/3.73, 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; wMaxPac
ketSize=49; nframes=6, buffer size=294
Если после подключения ничего не происходит - проверьте
работоспособность USB.
Запуск и остановка стека.
Для того, чтобы стек Bluetooth начал работать необходимо скопировать
/usr/share/examples/netgraph/bluetooth/rc.bluetooth, например в
/usr/local/etc/rc.bluetooth.
Теперь командой
# sh /usr/local/etc/rc.bluetoots start ubt0
мы запустим Bluetooth стек, а командой
# sh /usr/local/etc/rc.bluetoots stop ubt0
остановим его (рекомендуется перед вытаскиванием адаптера). Так
как адаптер без стека мне не сильно нужен я добавил такие команды в
/etc/usbd.conf
device "Bluetooth adapter"
vendor 0x1131
product 0x1001
attach "/usr/local/etc/rc.bluetooth start ${DEVNAME}"
detach "/usr/local/etc/rc.bluetooth stop ${DEVNAME}"
Теперь во время вставления адаптера (или при загрузке если он уже в
разьёме) стек будет автоматически включен. В файле rc.bluetooth
осуществляется загрузка модулей ng_hci(4), ng_l2cap(4),
ng_btsocket(4) и ng_bluetooth(4), создание и соединение
netgraph(4) нод. На мой взгляд в нём также целесообразно размещать
загрузку/выгрузку демонов, необходимых для работы Bluetooth.
Дополнительные настройки стека bluetooth доступны через переменные
sysctl(8) net.bluetooth.*.
Находим устройства
Теперь пришло время узнать MAC адреса наших устройств. Для этого
включаем Bluetooth в PDA и S55 (в том числе и "Local Discovery") и
запускаем поиск.
~: hccontrol -n ubt0hci inquiry
Inquiry result, num_responses=1
Inquiry result #0
BD_ADDR: 00:07:e0:45:ff:71
Page Scan Rep. Mode: 0x1
Page Scan Period Mode: 00
Page Scan Mode: 00
Class: 10:01:14
Clock offset: 0x7c71
Inquiry result, num_responses=1
Inquiry result #0
BD_ADDR: 00:01:e3:31:c8:53
Page Scan Rep. Mode: 0x1
Page Scan Period Mode: 00
Page Scan Mode: 00
Class: 72:02:04
Clock offset: 0xccb
Inquiry complete. Status: No error [00]
Как видно из вывода программы на наш запрос откликнулось 2 устройства.
Мы, конечно, можем узнать кто есть кто отключив одно из них и повторив
попытку, но есть и более удобный метод:
~: hccontrol -n ubt0hci remote_name_request 00:07:e0:45:ff:71
BD_ADDR: 00:07:e0:45:ff:71
Name: SammPalm
~: hccontrol -n ubt0hci remote_name_request 00:01:e3:31:c8:53
BD_ADDR: 00:01:e3:31:c8:53
Name: Samm phone
Кстати, было замечено что устройства часто неохотно говорят свое имя
сообщая:
Could not execute command "remote_name_request". Operation timed out
Теперь, когда нам известно кто есть кто - пропишем адреса устройств в
файл /etc/bluetooth/hosts добавив такие строки строки:
00:01:e3:31:c8:53 s55
00:07:e0:45:ff:71 palm
Это позволит нам в дальнейшем обращаться к устройствам по имени, а не
по адресу. Для проверки связи с устройством используется утилита
l2ping. l2ping нормально функционирует только из под рута (как и ping,
впрочем), но suid бита не имеет (видимо из-за соображений
безопасности).
# l2ping
# l2ping -a s55 -c 3
0 bytes from s55 seq_no=0 time=17.463 ms result=0
0 bytes from s55 seq_no=5 time=18.039 ms result=0
0 bytes from s55 seq_no=6 time=16.882 ms result=0
# l2ping -a palm -c 3
20 bytes from palm seq_no=0 time=1547.784 ms result=0
20 bytes from palm seq_no=1 time=37.662 ms result=0
20 bytes from palm seq_no=2 time=38.524 ms result=0
Palm во время ping`а высвечивает на экране Connecting и включает
звуковой сигнал, Siemens показывает на экране активность Bluetooth
соединения.
"Дружим" устройства
Для защиты соединения в протоколе Bluetooth предусмотрена процедура
обмена PIN кодом между устройствами (Bluetooth Pairing), после чего (в
случае совпадения PIN кода) создается ключ, с помощью которого и
шифруются данные. В OS FreeBSD за эту эти действия отвечает демон
hcsecd(8). Его настройки хранятся в файле
/etc/bluetooth/hcsecd.conf. Добавим туда наши устройства:
device {
bdaddr 00:07:e0:45:ff:71;
name "Palm Zire";
key nokey;
pin "12345";
}
device {
bdaddr 00:01:e3:31:c8:53;
name "Siemens S55";
key nokey;
pin "12345";
}
Теперь запустим /usr/sbin/hcsecd. Для отладки, в первый раз это можно
сделать с ключем -d, так мы сможем наблюдать за выводом демона.
Процедура создания ключа может быть инициирована как компьютером, так
и мобильным устройством (если оно это умеет). В случае Palm это можно
сделать используя меню prefs -> Bluetooth -> Setup Devices -> Trusted
Devices -> Add Device. Теперь выбираем в списке устройств ubt0 и
вводим назначенный ранее PIN. В случае успешного завершения операции
устройство будет добавлено в список Trusted. Демон hcsecd хранит
созданные ключи в файле /var/db/hcsecd.keys. S55 не умеет сам
инициировать процедуру создания ключа (по крайней мере, я не нашёл как
это сделать). При обращении к телефону с PC данная процедура будет
выполнена автоматически. Так как для работы с устройствами требуется
наличие hcsecd, я добавил его в rc.bluetooth.
Возможности Bluetooth
Теперь посмотрим, что мы можем делать с помощью Bluetooth. Протокол
Bluetooth предусматривает передачу данных (синхронную или асинхронную)
и передачу голоса. При этом устройства могут реализовывать только
нужную им функциональность стандарта. Протокол предусматривает
возможность спросить у устройства, какие возможности в нем
реализованы. В FreeBSD для этого используется утилита sdpcontrol.
Запустив sdpcontrol -a s55 browse мы получим подробный список
сервисов, поддерживаемых телефоном. Palm ничего не отвечает на эту
команду. Эксперементальным путем я выяснил, что Palm поддерживает
только OPUSH сервис (передача файлов). Узнать подробности о
интересующей нас службе можно набрав:
samm>~: sdpcontrol -a palm search OPUSH
Record Handle: 0x00010001
Service Class ID List:
OBEX Object Push (0x1105)
Protocol Descriptor List:
L2CAP (0x0100)
RFCOMM (0x0003)
Protocol specific parameter #1: u/int8/bool 1
OBEX (0x0008)
Передача файлов
Собственно, самое важное, что мне требовалось от Bluetooth - это
получить возможность передавать данные от/к устройствам без
использования кабелей. Для передачи файлов в мобильный устройствах
стандартом де-факто стал протокол OBEX. Для работы с этим
протколом в FreeBSD существует программа obexapp(1), которая находится
в дереве портов FreeBSD (/usr/ports/comms/obexapp). Протокол OBEX
позволяет передавать файлы используя OPUSH - простая передача файла от
одного устройства к другому и FTRN - полноценный доступ к файловой
системе устройства (удаление, копирование, создание папок и так
далее). Palm поддерживает только OPUSH протокол, S55 - как OPUSH так и
FTRN.
Доступ к FS мобильного телефона:
samm>~: obexapp -C FTRN -a s55 -f
obex> ls
Access Owner Group Size Modified Name
WD W n/a n/a n/a 01-Jan-02 00:00 Cache/
WD W n/a n/a n/a 01-Jan-02 00:00 PersistentData/
RWD W n/a n/a n/a 01-Jan-02 00:00 Animation/
RWD W n/a n/a n/a 01-Jan-02 00:00 Pictures/
RWD W n/a n/a n/a 01-Jan-02 00:00 Sounds/
RWD W n/a n/a n/a 01-Jan-02 00:00 Java/
RWD W n/a n/a n/a 01-Jan-03 00:03 Data objects/
WD W n/a n/a n/a 01-Jan-03 00:03 Address book/
WD W n/a n/a n/a 01-Jan-03 00:03 apo/
RWD W n/a n/a n/a 01-Jan-03 00:00 Internet/
WD W n/a n/a n/a 01-Jan-03 00:00 email/
RWD W n/a n/a n/a 07-Apr-04 16:45 Voice memo/
RWD W n/a n/a n/a 07-Apr-04 22:58 Text module/
RWD W n/a n/a n/a 07-Apr-04 23:02 Colour scheme/
RWD W n/a n/a n/a 11-Apr-04 10:13 Sms/
RWD W n/a n/a n/a 17-May-04 20:05 Misc/
Success, response: OK, Success (0x20)
Кроме того, OBEX резервирует некоторые имена файлов для специальных
функций. Так, через файловые операции можно удалять/добавлять записи в
телефонную книгу, календарь, просматривать параметры устройства и
изменять системное время. Например, для того, чтобы получить из
мобильника телефонный справочник (в формате vCard) следует
использовать команду obexapp -n -a s55 -f -C ircom get
"telecom/pb.vcf". Более подробная информация о использовании OBEX
находится в man файле obexapp.
Для передачи файлов используя протокол OPUSH введем obexapp -C OPUSH
-a palm -n PUT samm.txt после чего файл samm.txt будет передан на
Palm. Также вы можете настроить прием файлов по протоколу OPUSH на
локальный PC используя возможности obexapp.
PPP доступ к PC для Palm PDA
Для того, чтобы тестировать интернет приложения Palm и
синхронизироваться с PC (например, используя JPilot) я решил
настроить Bluetooth PPP доступ. Для того, чтобы наш компьютер смог
регистрировать локальные сервисы нам потребуется запустить демон sdpd
(/usr/sbin/sdpd). Для его автозапуска я прописал запуск и остановку
sdpd в файл rc.bluetooth.
Теперь займемся настройкой pppd. Для начала создадим запись для нашего
соединения в файле /etc/ppp/ppp.conf:
rfcomm-server:
set timeout 0
set lqrperiod 10
enable lqr
accept lqr
# Do not use PPP authentication. Assume that
# Bluetooth connection was authenticated already
disable pap
deny pap
disable chap
deny chap
accept dns
set ifaddr 10.0.1.1 10.0.1.2
Теперь запустим Bluetooth ppp сервер
# /usr/sbin/rfcomm_pppd -s -C 1 -l rfcomm-server -u 1
Набрав
# sdpcontrol -l browse
мы должны увидеть наш PPP сервис.
Теперь, настроив Bluetooth PPP соединение в PDA, можно подключаться к
сети. Для доступа в интернет следует настроить на PC NAT или Proxy.
Для синхронизации - выбираем в Palm network sync, адрес хоста
(10.0.1.1 в нашем примере). На PC прописываем в Jpilot устройство
net:any и выбираем синхронизацию. После этого выбираем sync на palm.
Должна начаться синхронизация.
Доступ к модему телефона и выход в интернет GPRS
В большинстве телефонов встроен модем, поддерживающий как стандартный
набор AT команд, так и расширенный синтаксис. Это позволяет звонить с
телефона, использовать GPRS интернет, отсылать SMS, синхронизировать
время и данные. Для доступа к серийному порту Bluetooth FreeBSD
содержит программу rfcomm_sppd(1). Запуск rfcomm_sppd -a s55 -t
/dev/ttypf позволит использовать устройство ttypf как обычный серийный
порт. Например:
samm>~: sudo cu -l /dev/ttypf
Connected
at
OK
atdp02
NO CARRIER
При этом вы можете использовать программы, работающие с телефоном
через COM шнурок (например - scmxx, /usr/ports/comm/scmxx) указав
вместо com порта назначенное устройство. Также существует возможность
использовать GPRS интернет (конечно, если ваш провайдер это
позволяет). Для выхода в интернет используется утилита
rfcomm_pppd(8). Ниже я опишу настройки для выхода в интернет
используя Kyivstar GPRS (корпоративный пакет).
Для начала создадим запись для нашего соединения в файле
/etc/ppp/ppp.conf
rfcomm-dialup:
enable force-scripts
# force dial script execution
set dial "ABORT BUSY \"\" \
ATE1 OK AT+CGDCONT=1,\\\"IP\\\",\\\"www.kyivstar.net\\\" OK \
ATD*99***1# CONNECT"
# set kyivstar APN in dial script
enable dns # if you're on local network and don't like ppp overwriting your
# resolv.conf every time you connect, comment this out
set authname igprs
set authkey internet
set ifaddr 0 0 255.255.255.0
add default HISADDR
Теперь пропишем в /etc/resolv.conf строку nameserver 0.0.0.0 (без
этого kyivstar не хотел назначать DNS) и попытаемся установить
соединение:
# rfcomm_pppd -a s55 -c -C dun -l rfcomm-dialup
# ping -c 3 193.193.193.100
PING 193.193.193.100 (193.193.193.100): 56 data bytes
64 bytes from 193.193.193.100: icmp_seq=1 ttl=56 time=1176.167 ms
64 bytes from 193.193.193.100: icmp_seq=2 ttl=56 time=683.977 ms
64 bytes from 193.193.193.100: icmp_seq=3 ttl=56 time=624.890 ms
Для того, чтобы завершить соединение достаточно убить процесс
rfcomm_pppd. Замечу, что качество соединения у компании kyivstar
невысокое, IP - серый, а цена трафика - огромна, так что данной
услугой имеет смысл пользоваться только там, где недоступны другие
способы выхода в сеть.
В завершение
Насколько мне известно, в настоящий момент в FreeBSD не реализована
возможность использования Bluetooth гарнитуры как dsp устройства (хотя
работы ведутся). Недавно данная возможность была реализована как
драйвер для ALSA Linux. В данный момент у меня нет гарнитуры для
экспериментов. Возможно, я приобрету это устройство, так как
возможность общения в Skype используя BT гарнитуру мне кажется
интересной идеей. Буду рад любым советам и дополнениям.
Я тут поигрался с блутусом, поэтому есть кое-какие дополнения.
Первое, про насройку стека. Сейчас (в 7.0-RELEASE) для включения bluetooth нужно только наличие модуля ng_ubt. Далее модуль находит устройство, и devd запускает /etc/rc.d/bluetooth ubt0 start. Ничего сверх загрузки ng_ubt делать не нужно. Демон hcsecd можно включить в /etc/rc.conf.
Далее, /etc/rc.d/bluetooth умеет конфигурировать устройства. Настройки он берет из /etc/defaults/bluetooth.device.conf, а затем из /etc/bluetooth/УСТРОЙСТВО.conf (УСТРОЙСТВО, надо думать, ubt0, но я не проверял т.к. не перегружался). Как обычно, в /etc/defaults ничего трогать не надо, поэтому:
cp /etc/defaults/bluetooth.device.conf /etc/bluetooth/ubt0.conf && vi /etc/bluetooth/ubt0.conf
Там можно указать класс устройства, необходимость аутентификации и шифрования, локальное имя, и как раз возможность нахождения устройства (discoverable) и подключения к нему (connectable). Параметры независимы и никак не влияют на возможность исходящих соединений. В моем случае, чтобы комп было видно с телефона, оба параметра должны быть в YES, ибо сначала телефон делает inquire, на который устройство откликнется своим маком в случае discoverable=YES, в потом (как минимум) remote_name_request, для которого нужно уже connectable=YES.
Если хотите поиграться руками с видимостью, это hccontrol Write_Scan_Enable. Inquiry Scan enabled -> устройство периодически просматривает эфир на предмет inquiry запросов, Page Scan enabled - соответственно на установление соединения. Оба выключены - устройство никак не будет реалировать на внешние раздражители, но само соединяться с кем либо сможет. Оба включены - устройство будет видно при поиске. Включен Page, но не Inquery - устройство не будет видно при поиске, но подключиться к нему (зная MAC или имея pairing в телефоне) будет можно.
Не гарантирую точности этой информации в спеки я не вчитывался, но эксперименты ее подтверждают.