Пингвин показывает зубки (Linux + Bluetooth...)
Автор: Олег Бройтман
http://phd.pp.ru/
phd@phd.pp.ru
Предоставлено специально для www.linuxrsp.ru
Как рассказано в предыдущей статье, свой
первый сотовый телефон автор выбрал с Bluetooth - стало интересно, что это
такое, и как этим пользоваться в Linux.
Bluetooth
Bluetooth - это технология связи,
предназначенная для беспроводного соединения между собой различных
устройств на небольшом расстоянии (10-30 метров) с невысокой скоростью (720
Кбит/сек.), хотя уже есть устройства, покрывающие расстояние до 100 метров
(на открытом пространстве), и разрабатываются устройства со скоростями до 2
Мбит/сек. Bluetooth использует нелицензируемый диапазон радиочастот 2.4
ГГц. Нелицензируемый - значит, для создания и распространения таких
устройств не требуется лицензии ведомств, заведующих связью. Bluetooth не
является альтернативой радио-ethernet (Wi-Fi), скорее, это
взаимодополняющие технологии. Wi-Fi - это именно радио-ethernet, в то время
как Bluetooth может соединять совершенно разнородные устройства, не только
компьютеры - например, сотовые телефоны, клавиатуры, мыши, принтеры, ПДУ и
телевизоры/видеомагнитофоны. Устройства Bluetooth могут объединятся в
пикосети (piconet), до 8 устройств в сети. Каждое устройство может
принадлежать нескольки сетям, до 72 устройств в сети, называемой
scatternet.
Своё необычное название протокол получил благодаря историческому курьёзу.
Король Дании Харальд, правивший с 940 по 985 года, имел прозвище "голубой
зуб" из-за дефекта (вероятно, просто порчи) зуба. В 960 году он присоединил
(взял под протекцию) королевство своей овдовевшей сестры Норвегию. Вот
из-за этого объединения протокол, объединяющий разнородные устройства, и
получил своё имя. Начало он получил в исследовательской лаборатории
шведской фирмы Ericsson.
Bluetooth в Linux
Начнём издалека. Протоколом в computer science называется стандарт, который
определяет, как происходит обмен информацией между различными поставщиками
и получателями этой самой информации. Протокол позволяет абстрагировать
процесс передачи информации как от низкоуровневых деталей реализации, так и
от содержимого передаваемой информации. Например, протокол HTTP
определяет понятия "ресурс", "запрос", "ответ", синтаксис запроса и ответа,
но не определяет, какая именно информация будет передаваться в запросах и
ответах; одна программа (робот) может сохранять результаты запросов
(ответы) в файлы или базу данных, другая (браузер) отображает эту
информацию (интерпретируя HTML, картинки и прочие типы файлов).
Протоколы группируются в стеки. Один протокол использует другой в качестве
транспорта, несущего его высокоуровневую информацию, и таких слоёв может
быть довольно много. Например, протокол TCP использует протокол IP в
качестве транспорта, передающего его, протокола TCP, данные. Протокол HTTP
использует в качестве транспортного уровня уже TCP. Протокол XML-RPC
использует HTTP; он мог бы использовать, скажем, SMTP, но это уже экзотика.
Реализации протоколов тоже выстраиваются в стеки. На самом нижнем уровне
доступ к конкретному устройству осуществляет драйвер устройства. Ядро
операционной системы предоставляет пользовательским программам стандартный
интерфейс к драйверам. В свою очередь хорошо написанные программы не сами
реализуют этот доступ, а пользуются библиотеками, реализующими протоколы
более высоких уровней.
Так вот, существует 3 стека протоколов Bluetooth для Linux, то есть 3
реализации. Основной - Bluez, был
разработан в Qualcomm. Этот стек включён в ядро Linux начиная с версии
2.4.18. Другой стек, включённый в ядро -
OpenBT фирмы
Axis. Оба стека требуют программ и библиотек, которые можно скачать с
указанных сайтов. Третий стек -
Affix - разработан Nokia. Он не
включён в ядро Linux, для его установки требуется скачать и установить патч
ядра, плюс опять-таки библиотеки и программы. Недостатком Affix является
именно то, что он не интегрирован в ядро. С другой стороны, он имеет такое
(несколько экзотическое) достоинство, как PyAffix - патч для модуля socket
стандартной библиотеки языка программирования
Python, добавляющий протокол Bluetooth
к списку поддерживаемых протоколов.
Bluez
Остановимся на стеке Bluez; он интегрирован в ядро, считается основной
реализацией Bluetooth, имеет
драйверы
для множества устройств. Включаем его в ядре, и, пока ядро компилируется,
заглядываем в любимые Интернет-магазины, и в ближайшем находим подходящие
устройства. Автор остановился на устройствах фирмы Bluetake c чипсетом
CSR. Их
достоинство в том, что драйвер hci_usb их уже поддерживает; в то время как
для устройств Broadcom надо ещё скачивать firmware (загружаемую прошивку) и
налаживать загрузку прошивки при каждом включении устройства; к такой
загрузке прошивок автор относится с недоверием - мало ли в какой версии
устройства способ загрузки прошивки будет изменён, и драйвер Linux работать
перестанет; в то время как устройства с известным интерфейсом обычно
обладают стабильностью. В телефоне Siemens S55 10-метровое устройство
Bluetooth, подходит устройство Bluetake 009X. Однако не всё так просто.
Оказалось, устройства Bluetooth раскупаются со страшной силой, и на складе
были только 100-метровые Bluetake 007X. По цене они отличались не сильно, и
если нет причин требовать именно 10-метрового Bluetake 009X (у автора не
было) - можно купить и 100-метровое. Пригодится не только для телефона.
Скажем, на дачном участке соединить 2 компьютера на соседних улицах безо
всяких проводов.
После компиляции ядра с Bluez'ом устанавливаем его, перезагружаемся, и
принимаемся компилировать библиотеки и программы. Автор решил не ставить
бинарные пакеты (на сайте Bluez есть готовые
пакеты для Debian и
RedHat), а поизучать, что у них там внутри, как они компилируются и
устанавливаются. А чтобы было проще потом всё удалить, если всё-таки
захочется поставить эти пакеты, всё устанавливаем в директорию
/usr/local/bluez. Запускаем во всех каталогах
./configure --prefix=/usr/local/bluez, потом make и make install. Тут нас
ждёт маленькая засада. Все программы и файлы конфигурации там заточены под
установку в стандартные директории. Устанавливаются-то они куда надо, но
ссылаются друг на друга по абсолютным путям, например,
/etc/bluetooth/hcid.conf. Приходится во все нужные места ставить симлинки
на реальные файлы и каталоги.
Воткнув устройство, загружаем его драйвер: modprobe hci_usb. Заглянем в
syslog - опознал ли драйвер устройство? Загружаем демоны:
/etc/init.d/bluetooth start. Проверяем: hciconfig -a. Есть устройство hci0,
состояние UP and RUNNING. Всё в порядке. Проверяем связь с телефоном.
Включаем Bluetooth в телефоне, прописываем ему имя покрасивее, делаем его
видимым для всех (это такая мера безопасности - устройство можно сделать
невидимым, и тогда обращаться к нему можно, только зная его адрес).
Проверяем, видит ли компьютер телефон: hcitool scan. Bluetake заморгал
своей синей лампочкой (в норме он моргает редко, а тут поскакал
сигнализировать о трафике), hcitool задумался... и нашёл одно устройство.
Показал его адрес (каждому устройству Bluetooth присвоен уникальный адрес,
наподобие адреса ethernet) и имя. Всё в порядке, увидел!
Тут над немножко сказать про PIN-коды. Bluetooth имеет встроенные механизмы
безопасности. Имеются средства аутентификации и шифрования трафика. Для
доступа к устройству используется секретный PIN-код, который должен быть
введён во все устройства, которым разрешается связь друг с другом.
Программы стека Bluez могут спрашивать этот PIN у пользователя
интерактивно... но это не работает. Программа /usr/local/bluez/bin/bluepin,
прописанная в конфигурационном файле /etc/bluetooth/hcid.conf, требует для
своей работы Python и PyGTK2. И Python, и PyGTK2 не проблема, но толку от
них мало. Программа эта должна вызываться из демона hcid, и при этом иметь
доступ к X-серверу. Такой доступ из демона открывать не рекомендуется, да и
XWindows не всегда запущен. Значит, придётся обойтись без интерактивности.
Да и не нужна она, такую информацию предпочтительнее держать в файлах
конфигурации. Демон hcid ожидает от этой программы ответ в формате PIN:pin,
где pin - секретный код. Теоретически это, наверное, может быть любой код,
но телефон позволяет ввести только код, целиком состоящий из цифр, поэтому
надо создать скриптик /usr/local/bluez/bin/simplepin:
echo PIN:1234
и прописать его в /etc/bluetooth/hcid.conf. Не все телефоны в равной мере
поддерживают эти средства безопасности. Некоторые "дырявые" телефоны имеют
проблемы
bluejacking и
bluesnarfing,
позволяющие удалённо читать данные с телефона без разрешения владельца, и
даже заставить телефон звонить или послать SMS. С
S55
проблем пока не обнаружено.
Убедившись, что Bluez обнаружил в радиусе действия телефон, проверяем связь.
l2ping 00:CP:AD:RE:SS (будем считать, что это адрес телефона из выдачи
команды hcitool scan). Телефон запросил PIN. Вводим 1234. Телефон
предлагает запомнить найденное устройство в списке известных устройств.
Сохраняем - это позволит запомнить PIN и не вводить его каждый раз при
установке соединения. Тем временем l2ping показывает, что от телефона пошли
ответы. Есть связь! Теперь можно переключить Bluetooth в телефоне в режим
невидимости - телефон перестанет показывать свой адрес в hcitool scan, и к
нему не смогут присоединиться те, кто не знает его адреса. Но мы-то теперь
адрес телефона знаем, и можем легко устанавливать с ним связь, даже когда
он "невидим".
Hotplug
Hotplug - это механизм "горячего" подключения, то есть включения и
выключения устройств без выключения и перезагрузки компьютера. Не всякая
шина позволяет осуществлять "горячее" подключение, скажем, IDE и RS-232 не
позволяют вовсе (во всяком случае, не рекомендуется). Шины PCI - только
некоторые реализации, и только некоторые устройства. А вот шины USB и
SerialATA и все устройства позволяют подключаться "на лету". Когда
пользуешься устройствами USB редко, нужды в настройке hotplug нет. Раз в
полгода вставишь flash-карту, так драйвер можно и руками загрузить. А вот
устройство, которое собираешься использовать довольно часто, лучше бы
автоматизировать - пусть при включении/отключении Linux сам загружает и
выгружает драйверы и демоны. Держать его постоянно включённым не хочется -
неизвестно, что там излучает 100-метровый передатчик. Ставим пакет hotplug,
подключаем устройство, смотрим в syslog. Hotplug устройство не опознал.
Вынимаем устройство, загружаем драйвер Bluez - modprobe hci_usb, вставляем
устройство. Hotplug опознал его как устройство bluetooth, пишет, что не
нашёл программы /etc/hotplug/bluetooth.agent. Ага, ясно, значит драйвер
hci_usb надо добавить в /etc/modules, чтобы он загружался автоматически при
старте системы, и опознавал устройство. А man hotplug рассказал, что agent
- это программа, которой в переменной окружения ACTION передаётся команда
add или remove, а всё остальное - на усмотрение программы. Быстрая проверка
показывает, что это не совсем правда - команды не add и remove, а register
и unregister. Дальше всё просто - в файл /etc/hotplug/bluetooth.agent
пишется скрипт:
if [ "$ACTION" = register ]; then
exec /etc/init.d/bluetooth start
elif [ "$ACTION" = unregister ]; then
exec /etc/init.d/bluetooth stop
fi
Делаем файл выполняемым. Hotplug работает!
Теперь надо использовать связь компьютера и телефона каким-нибудь разумным
образом - наладить сохранение записной книжки, загрузить в телефон файлы,
подключить GPRS. В следующий раз.
См. также:
Алё, говорит Linux. Как слышно? Приём! (Linux + OBEX + GPRS...) (Олег Бройтман)
Алё! Пингвин ищет телефон (Linux + Siemens...) (Олег Бройтман)