Bluetooth CLI
Jun. 23rd, 2008 02:54 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Тут в предыдущем треде была поднята тема форка bluez-utils. Подумавши немного, я пришел к выводу, что тут нужен не форк, вернее не совсем форк. Существующие bluez-utils это фактически отладочные инструменты для проверки работоспособности bluetooth-стека и libbluetooth. Поэтому понятно что для работы они не приспособлены.
Хотя надо сказать, во времена оны делали по другому. Возьмем, к примеру стэк TCP/IP. На протяжении десятилетий для отладки tcp/ip протоколов пользовались telnet - программой, которая вообще-то предназначена для РАБОТЫ с одним из протоколов, но заодно и обладает отладочными возможностями - просто передавать ввод-вывод на указанный TCP/IP сервер. И только много позже появился netcat. Который вообще-то тоже не для отладки предназначен, а для скриптования.
Разработчики bluez не шмогли разработать такой набор утилит, который был бы удобен и для отладки, и для работы. Ну да хрен бы с ними. Надо просто разработать более другой набор утилит, предназначеный для реализации типичных сценариев работы пользователя с bluetooth-подсистемой и заточенный для использования из скриптов, так чтобы можно было легко и удобно реализовывать нетипичные сценарии. libbluetooh, hcid и bluetooth-подсистему в ядре по умолчанию считаем спроектированными правильно, и пригодными к употреблению. Ежели в процессе работы выяснится что это не так, тогда и будем думать как править.
Кстати, не исключено что надо сразу зарекаться на работоспособность утилит с более другими стэками bluetooth, например FreeBSD-шным. Там местами сделано более правильно.
Рассмотрев те сценариии использования bluetooth, которые приходилось использовать мне я пришел к выводу, что нужны следующие инструменты:
1. Система bluetooth name resolution. Ибо не юзерское это дело - 12-разрядные шестнадцатиричные числа запоминать. Вот в том же TCP/IP моментально перешли от 48-битных MAC-адресов к 32-битным IP, да и над теми DNS нагородили. Поэтому нужно обеспечить возможность ВЕЗДЕ, где указывается bluetooth-адрес, указывать удобочитаемое имя устройства.
Проблема, конечно, что в Bluetooth нет никакой централизованной authority, назначающей имена. Имя задается на самом устройстве, и из коробки два устройства одинаковой модели имеют одинаковые имена. Но будем исходить из того что пользователь все-таки не совсем дебил, и знает где в настройках устройства кнопка set name. Поэтому обеспечить удобную ему уникальность имен среди принадлежащих ему устройств он может. И, что характерно, хочет. Появление в эпсилон окресности чужого устройства с тем же именем, в большинстве случаев надо просто игнорировать. Если у нас есть non-discoverable устройство, с которым мы уже спарены, и discoverable устройство с таким же именем, по умолчанию считаем что нам нужно первое. В конце-концов если ничего не другое не помогает пользователь всегда сможет указать явный адрес, и это будет не хуже, чем сейчас.
Вообще по-моему, это можно сделать на уровне плагинов к libnss. Благо AF_BLUETOOTH - это просто yet another address family для сокетов. Но если не получится можно отдельную libbtns написать.
2. BTPasskey. Утилита для обслуживания dbus-интерфейса запроса пинкодов. Вообще-то я уже его написал. В Debian Cosy оно есть. Хотя стоило бы немножко доделать
а) выводить имя устройства, которое просит пин, а не только его адрес (см п.1)
б) уметь на время ожидания PIN включать discoverablity через d-bus интерфейс к hcid.
в) ежели оно запущено не пайпом из GUI а просто из xterm, уметь этот xterm поднимать наверх, деиконидировать и вообще всячески требовать внимания пользователя (естественно, по явной просьбе оного пользователя).
3. Управлялка состояния интерфейсом. Хотя бы discoverable/connectable включать/выключать.
4. НЕкоторый набор функций hcitool и sdptool, только с более удобным как для юзера, так и для скритов интерфейсом
а) ping проверить наличие определенного устройства (например, с помощью аналога hcltool name). Если устройство знакомое (например уже спаренное) то оно должно обнаруживавться, даже если оно не discoverable (но connectable, иначе работать с ним мы все равно не сможем). Должно возвращать ненулевой код завершения, если устройство не обнаружено. Крайне желательно чтобы умело отвалиться заметно быстрее, чем умолчательный таймаут у hcitool name.
б) Аналог sdptool browse, но форматом более пригодным как зля обзора глазками, так и для парсинга скриптами.
в) Аналог sdptool search, но ориентированный на использование из скриптов. То есть не нулевой код завершения, если ни одного девайса, предоставляющего данный профайл не нашлось.
г) то же самое, что в), но с возможностью явно указать список адресов/имен устройств. Ищет именно в том порядке в каком указано и возвращает первый найденный. Таким образом можно искать, например точку доступа NAP - сначала проверили свой десктоп, нет его не видно, проверили свой сотовый - тоже не видно, пошли обнюхивать незнакомые устройства.
5. Аналог rfcomm_sppd из freebsd - демон, который слушает запросы на определенном канале, и буде запрос пришел, устанавливает rfcomm-соединение и напускает на него указанную программу. Т.е. хрень, которая позволит залогиниться на машину консолью,
посредством rfcomm bind /dev/rfcommX address; cu -l /dev/rfcommX.
Логиниться черед bluetooth как эмуляцию последовательного порта - это экзотика, но у меня по крайней мере один use case есть. Главное же в другом - последовательный терминал наиболее полно эксплуатирует возможности последовательного порта. И если мы сумели сэмулировать последовательное подключение к unix-хосту, то сэмулировать bluetooth gps через какой-нибудь gpsd мы сумеем (что, кстати, открывает возможности использования Nokia N810 с её встроенным GPS как обычного bluetooth GPS, подключаемого к более другой системе)
6. pan manager. Bluetooth PAN -это очень интересная вещь. Если rfcomm - это эмуляция последоветельного порта, то PAN - это эмуляция эзернет. К сожалению, почему-то такую классную штуку недооценивают. Производители сотовых телефонов, правда подтянулись, и многие телефоны уже умеют пускать в internet по NAP, а не по DUN. Но вот в Nokaa N800 поддержки PAN в GUI connection manager почему-то нет (из командной строки все работает) а во FreeBSD вообще его забыли реализовать.
pand, входящий в bluez-utils немного кривоват. Чего бы хотелось:
а) опции updetach, аналогичной pppd - то есть висим в foreground пока не удалось установить соединение, если что не так, рассказываем на stderr и завершаемся с ненулевым кодом. А если все получилось и интерфейс поднялся, уходим в background, и не мешаем работать.
б) автоматического выбора из нескольких точек доступа по приоритетности (аналогично wpa_supplicant)
в) удобного режима организации ad-hoc сетей. Чтобы можно было одним движением запустить эту штуку в роли мастера пикосети, а остальные машины туда бы радостно коннектились (возможно, с одновременным спариванием) и получали бы IP по dhcp, резолвинг имен и все такое хорошее (для чего в дистрибутиве есть dnsmasq). Соттветственно в роли клиента (PANU) нужен режим "входить в незнакомую ранее сеть с одновременным спариванием"
7. obex ftp. Вообще-то obexftp это не из bluez-utils, это отдельный пакет. Но у bluetooth тут есть своя специфика. Очень многие устройства, например телефоны Ericsson, требуют от пользователя интерактивного, на клавиатуре телефона, подтверждения что данному компьютеру можно копаться в их файлах. Подтверждение это требуется раз за сессию, поэтому интерфейс старого доброго /usr/bin/ftp или smbclient был бы идеален. К сожалению, интерфейс у obexftp другой - одна команда один запуск (и соответственно, не выходя за пределы сессии просмотреть результаты команды ls, а потом чему-то из этого сделать get, а чему-то delete - нельзя). Да, и конечно, результат команды ls должен быть похож на результат ls, а не представлять собой xml-файл.
С obexftp сервером проще. Хотя к obexftpd у меня тоже какие-то претензии были. Надо посмотреть на последнюю версию.
8. obex push - тут нужы две вещи - удобная посылалка объектов, (впрочем t68tool --push это почти оно) и сервер.
Сервер может быть per system, работающий даже если никто не залогинен, и per session. В первом случае нужно внимательно думать куда и с какими правами складывать принятые файлы, кого и как об этом уведомлять. С per session все несколько проще. Но нужно научиться не конфликтовать с per-system, если он запущен.
Это то, что мне придумалось исходя из моего опыта использования различных bluetooth-устройств. Всякие прочие user stories, предложения и дополнения приветсвуются
Хотя надо сказать, во времена оны делали по другому. Возьмем, к примеру стэк TCP/IP. На протяжении десятилетий для отладки tcp/ip протоколов пользовались telnet - программой, которая вообще-то предназначена для РАБОТЫ с одним из протоколов, но заодно и обладает отладочными возможностями - просто передавать ввод-вывод на указанный TCP/IP сервер. И только много позже появился netcat. Который вообще-то тоже не для отладки предназначен, а для скриптования.
Разработчики bluez не шмогли разработать такой набор утилит, который был бы удобен и для отладки, и для работы. Ну да хрен бы с ними. Надо просто разработать более другой набор утилит, предназначеный для реализации типичных сценариев работы пользователя с bluetooth-подсистемой и заточенный для использования из скриптов, так чтобы можно было легко и удобно реализовывать нетипичные сценарии. libbluetooh, hcid и bluetooth-подсистему в ядре по умолчанию считаем спроектированными правильно, и пригодными к употреблению. Ежели в процессе работы выяснится что это не так, тогда и будем думать как править.
Кстати, не исключено что надо сразу зарекаться на работоспособность утилит с более другими стэками bluetooth, например FreeBSD-шным. Там местами сделано более правильно.
Рассмотрев те сценариии использования bluetooth, которые приходилось использовать мне я пришел к выводу, что нужны следующие инструменты:
1. Система bluetooth name resolution. Ибо не юзерское это дело - 12-разрядные шестнадцатиричные числа запоминать. Вот в том же TCP/IP моментально перешли от 48-битных MAC-адресов к 32-битным IP, да и над теми DNS нагородили. Поэтому нужно обеспечить возможность ВЕЗДЕ, где указывается bluetooth-адрес, указывать удобочитаемое имя устройства.
Проблема, конечно, что в Bluetooth нет никакой централизованной authority, назначающей имена. Имя задается на самом устройстве, и из коробки два устройства одинаковой модели имеют одинаковые имена. Но будем исходить из того что пользователь все-таки не совсем дебил, и знает где в настройках устройства кнопка set name. Поэтому обеспечить удобную ему уникальность имен среди принадлежащих ему устройств он может. И, что характерно, хочет. Появление в эпсилон окресности чужого устройства с тем же именем, в большинстве случаев надо просто игнорировать. Если у нас есть non-discoverable устройство, с которым мы уже спарены, и discoverable устройство с таким же именем, по умолчанию считаем что нам нужно первое. В конце-концов если ничего не другое не помогает пользователь всегда сможет указать явный адрес, и это будет не хуже, чем сейчас.
Вообще по-моему, это можно сделать на уровне плагинов к libnss. Благо AF_BLUETOOTH - это просто yet another address family для сокетов. Но если не получится можно отдельную libbtns написать.
2. BTPasskey. Утилита для обслуживания dbus-интерфейса запроса пинкодов. Вообще-то я уже его написал. В Debian Cosy оно есть. Хотя стоило бы немножко доделать
а) выводить имя устройства, которое просит пин, а не только его адрес (см п.1)
б) уметь на время ожидания PIN включать discoverablity через d-bus интерфейс к hcid.
в) ежели оно запущено не пайпом из GUI а просто из xterm, уметь этот xterm поднимать наверх, деиконидировать и вообще всячески требовать внимания пользователя (естественно, по явной просьбе оного пользователя).
3. Управлялка состояния интерфейсом. Хотя бы discoverable/connectable включать/выключать.
4. НЕкоторый набор функций hcitool и sdptool, только с более удобным как для юзера, так и для скритов интерфейсом
а) ping проверить наличие определенного устройства (например, с помощью аналога hcltool name). Если устройство знакомое (например уже спаренное) то оно должно обнаруживавться, даже если оно не discoverable (но connectable, иначе работать с ним мы все равно не сможем). Должно возвращать ненулевой код завершения, если устройство не обнаружено. Крайне желательно чтобы умело отвалиться заметно быстрее, чем умолчательный таймаут у hcitool name.
б) Аналог sdptool browse, но форматом более пригодным как зля обзора глазками, так и для парсинга скриптами.
в) Аналог sdptool search, но ориентированный на использование из скриптов. То есть не нулевой код завершения, если ни одного девайса, предоставляющего данный профайл не нашлось.
г) то же самое, что в), но с возможностью явно указать список адресов/имен устройств. Ищет именно в том порядке в каком указано и возвращает первый найденный. Таким образом можно искать, например точку доступа NAP - сначала проверили свой десктоп, нет его не видно, проверили свой сотовый - тоже не видно, пошли обнюхивать незнакомые устройства.
5. Аналог rfcomm_sppd из freebsd - демон, который слушает запросы на определенном канале, и буде запрос пришел, устанавливает rfcomm-соединение и напускает на него указанную программу. Т.е. хрень, которая позволит залогиниться на машину консолью,
посредством rfcomm bind /dev/rfcommX address; cu -l /dev/rfcommX.
Логиниться черед bluetooth как эмуляцию последовательного порта - это экзотика, но у меня по крайней мере один use case есть. Главное же в другом - последовательный терминал наиболее полно эксплуатирует возможности последовательного порта. И если мы сумели сэмулировать последовательное подключение к unix-хосту, то сэмулировать bluetooth gps через какой-нибудь gpsd мы сумеем (что, кстати, открывает возможности использования Nokia N810 с её встроенным GPS как обычного bluetooth GPS, подключаемого к более другой системе)
6. pan manager. Bluetooth PAN -это очень интересная вещь. Если rfcomm - это эмуляция последоветельного порта, то PAN - это эмуляция эзернет. К сожалению, почему-то такую классную штуку недооценивают. Производители сотовых телефонов, правда подтянулись, и многие телефоны уже умеют пускать в internet по NAP, а не по DUN. Но вот в Nokaa N800 поддержки PAN в GUI connection manager почему-то нет (из командной строки все работает) а во FreeBSD вообще его забыли реализовать.
pand, входящий в bluez-utils немного кривоват. Чего бы хотелось:
а) опции updetach, аналогичной pppd - то есть висим в foreground пока не удалось установить соединение, если что не так, рассказываем на stderr и завершаемся с ненулевым кодом. А если все получилось и интерфейс поднялся, уходим в background, и не мешаем работать.
б) автоматического выбора из нескольких точек доступа по приоритетности (аналогично wpa_supplicant)
в) удобного режима организации ad-hoc сетей. Чтобы можно было одним движением запустить эту штуку в роли мастера пикосети, а остальные машины туда бы радостно коннектились (возможно, с одновременным спариванием) и получали бы IP по dhcp, резолвинг имен и все такое хорошее (для чего в дистрибутиве есть dnsmasq). Соттветственно в роли клиента (PANU) нужен режим "входить в незнакомую ранее сеть с одновременным спариванием"
7. obex ftp. Вообще-то obexftp это не из bluez-utils, это отдельный пакет. Но у bluetooth тут есть своя специфика. Очень многие устройства, например телефоны Ericsson, требуют от пользователя интерактивного, на клавиатуре телефона, подтверждения что данному компьютеру можно копаться в их файлах. Подтверждение это требуется раз за сессию, поэтому интерфейс старого доброго /usr/bin/ftp или smbclient был бы идеален. К сожалению, интерфейс у obexftp другой - одна команда один запуск (и соответственно, не выходя за пределы сессии просмотреть результаты команды ls, а потом чему-то из этого сделать get, а чему-то delete - нельзя). Да, и конечно, результат команды ls должен быть похож на результат ls, а не представлять собой xml-файл.
С obexftp сервером проще. Хотя к obexftpd у меня тоже какие-то претензии были. Надо посмотреть на последнюю версию.
8. obex push - тут нужы две вещи - удобная посылалка объектов, (впрочем t68tool --push это почти оно) и сервер.
Сервер может быть per system, работающий даже если никто не залогинен, и per session. В первом случае нужно внимательно думать куда и с какими правами складывать принятые файлы, кого и как об этом уведомлять. С per session все несколько проще. Но нужно научиться не конфликтовать с per-system, если он запущен.
Это то, что мне придумалось исходя из моего опыта использования различных bluetooth-устройств. Всякие прочие user stories, предложения и дополнения приветсвуются