phdru.name / Russian / Admin / cellphones

Пингвин показывает зубки

Автор: Олег Бройтман
http://phd.pp.ru/
phd@phd.pp.ru

Перепечатка. Оригинал статьи опубликован по адресу http://www.linuxrsp.ru/artic/Linux-Bluetooth.html

Как рассказано в предыдущей статье, свой первый сотовый телефон автор выбрал с 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. В следующий раз.


Эта страница http://phdru.name/Russian/Admin/cellphones/Linux_Bluetooth.html была сгенерирована 08.06.2014 в 20:52:32 из шаблона CheetahTemplate Linux_Bluetooth.tmpl; Некоторые права зарезервированы. Вы можете узнать о технических аспектах этого сайта.