Октодон: going deeper underground

Октодон: going deeper underground

В этом очерке мне бы хотелось мало отойти от истории клавиатуры Октодон и поведать о настоящих проблемах, с которыми мы сталкивались на различных стадиях разработки прототипов. Так выходит, что ни при каких обстоятельствах не знаешь, как сложной будет стыковка высокоуровневого API (в нашем случае Android API) и самодельного железа. Подводные камни подстерегают практически на каждом шагу, и ни при каких обстоятельствах не можешь кроме того примерно оценить, как трудоёмка та либо другая задача.

Учитывая вдобавок, что время ограничено — неизменно на носу какая-нибудь выставка либо презентация, к которой прототип уже обязан трудиться, решения приходится изыскивать всеми методами
Смотрите кроме этого: Как за 5 мин. оказать помощь выйти на Кикстартер

Проект «Октодон» формирует новый стандарт ввода текста в смартфоны. Вы имеете возможность оказать помощь нам в подготовке кампании на Кикстартер, ответив всего на 3 вопроса и израсходовав не более 5 мин. времени. Ваша помощь серьёзна для нас, поскольку на Хабре – отечественная целевая аудитория, как раз ваши рекомендации оказывают помощь нам сделать клавиатуру таковой, какой её желаете видеть вы – будущие пользователи.Если вы смотрите за судьбой проекта, имеете возможность пропустить вводную часть и перейти сходу к опросу.

photo by Patrick Pleul/AFP/Getty Images… и итог редко получается красивым.Я участвую в создании Октодона как Android-разработчик, радиомонтажник и электронщик. Так оказалось, что не обращая внимания на то, что в последние пара лет моя главная деятельность — это высокоуровневая разработка на .NET, детство моё было осчастливлено компьютером ZX Spectrum и ассемблером для процессора Z80.

В следствии я через чур рано начал понимать, как компьютер трудится на уровне временных диаграмм и сигналов, и это не имело возможности не наложить отпечатка — я до сих пор весьма обожаю низкоуровневую разработку. И в то время, когда мне внесли предложение поучаствовать в проекте создания принципиально новой клавиатуры, “железки”, я просто не смог отказаться.Хаками (а в противном случае и не назвать), про каковые я на данный момент поведаю, я совсем не горжусь.

Но они разрешили проекту расти и развиваться, разрешили иметь не обнажённую идею, а рабочую реализацию, талантливую завлекать заинтересованных лиц, инвесторов и будущих пользователей. На нынешнем этапе развития целый данный код уже не употребляется, не переживайте :)Быть может, что для более полной картины того, чем мы по большому счету занимаемся, вам будет весьма интересно прочесть прошлый пост, написанный отечественным предводителем AlexLysenko: Клавиатура Октодон в отыскивании Верного КликаПрототип №1 — BluetoothНаш первый прототип применял обмен через Bluetooth.

Казалось бы, не может быть более эргономичной технологии для телефона и соединения клавиатуры, и была уверенность, что всё получит из коробки. Но этого не произошло.Первая неприятность появилась с тем, что, начиная с версии 2.3, в Андроиде показалась встроенная в совокупность помощь BT-клавиатур. Когда совокупность обнаруживала “спаренную” клавиатуру, то тут же захватывала её и начинала применять как средство ввода.

Потому, что то же самое планировали делать и мы, у нас неминуемо на одно нажатие джойстика Октодона печаталось бы два знака — “отечественный” и “системный”. Требовалось как-то приглушить излишне говорливого Андроида. Телефон был “рутован”, и началось копание в исходниках системных библиотек и ядра с целью отыскать самоё удобное место, где возможно было бы проигнорировать подключение клавиатуры.

Таким местом была библиотека libui.В функцию open_device был внедрен нечистый хак вида:if ((id.vendor == 0x05AC id.product == 0x0239)) // VID и PID отечественной клавиатуры { LOGI(Ignoring device %04x %04x, id.vendor, id.product); close(fd); fd = -1; return -1; } Как видно, мы просто не позволяем открыть отечественное устройство. Сейчас ОС прекратила отбирать у нас клавиатуру, и с ней стало вероятно общаться, применяя Bluetooth-функции Android API.

В этот самый момент опять поджидала неприятность: никак не получалось открыть BT-сокет для приёма данных — стандартная для этого функция createRfcommSocketToServiceRecord падала с неточностью. Анналы истории не сохранили подробностей, но неприятность забрала довольно много времени. В итоге дело дошло до реверс-инжиниринга продуктов из (тогда ещё) Маркета, разрешавшим трудиться с данной BT-клавиатурой на “ветхих” Андроидах, каковые не умели делать этого сами.

И вот за баррикадами обфускации в одной из программ было обнаружено красивое:private static BluetoothSocket createBluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address, int port) { try { Class[] parameterTypes = new Class[] { Integer.TYPE, // type Integer.TYPE, // fd Boolean.TYPE, // auth Boolean.TYPE, // encrypt String.class, // address Integer.TYPE// port };Constructor constructor = BluetoothSocket.class.getDeclaredConstructor(parameterTypes); constructor.setAccessible(true);Object[] parameters = new Object[] { Integer.valueOf(type), Integer.valueOf(fd), Boolean.valueOf(auth), Boolean.valueOf(encrypt), address, Integer.valueOf(port), };return (BluetoothSocket)constructor.newInstance(parameters); } catch (Exception ex) { return null; } } BluetoothSocket intrSocket = createBluetoothSocket(3 /* TYPE_L2CAP */, -1, false, false, DC:2C:26:A0:C2:50 /* MAC-address */, 0x13 /* INTR port */); Вызов private-конструктора типа! Удивление стало ещё громадным, в то время, когда представленный кусок кода забрал и сразу же получил.

Разбираться, что, как и из-за чего уже не было времени, исходя из этого код был покинут прямо в таком виде. В этом один из минусов низкоуровневой разработки — довольно часто приходится смиряться с тем, что часть кода трудится “магически”: только бог ведает, из-за чего оно трудится, и только бог ведает, из-за чего более обычное ответ трудиться отказывается… К счастью, мы скоро ушли от данной Bluetooth-клавиатуры, сделав с её применением лишь один прототип, исходя из этого от таковой “магии” скоро удалось избавиться.Прототип №2 — USB HID-клавиатураКак лишь стало ясно, что применение готовых устройств нас очень сильно ограничивает, было решено разрабатывать собственное.

Главным смартфоном, на что мы ориентировались, к этому времени стал Samsung Galaxy S2. У него был нормально и стабильно трудящийся USB-host, к которому мы и планировали подключиться. В качестве контроллера была забрана Teensy 1.0. Весьма не своевременно оказалось, что её возможностей нам мало, и что брать-то следовало более свежую версию, 2.0.

Отличие было в библиотеках для HID-совместимых устройств. В случае если 1.0 умела прикидываться лишь HID-клавиатурой либо мышкой, то на 2.0 возможно было реализовать значительно более универсальное устройство Raw HID, применяющее отечественный личный протокол. Но что сделать, вначале было нужно ограничиваться тем, что было.

При эмуляции HID-клавиатуры опять появилась обрисованная выше неприятность — при подключении совокупность сама захватывала её как устройство ввода, и отправляемые знаки печатались два раза — нами и ОС.Обрисованное же выше ответ уже не годилось — сделали вывод, что с нас хватит трансформаций совокупности. В случае если мы желаем создать устройство, которое возможно выпустить на рынок, то оно должно трудиться на любом Galaxy S2, не должно быть необходимости в обновления firmware.

В ходе опытов с простой USB-клавиатурой, подключенной к S2, стало известно, что смартфон почему-то не реагирует на нажатия кнопок в цифровой части клавиатуры. Это стало важным подспорьем, поскольку отечественная Teensy имела возможность каким-то образом кодировать отклонения джойстиков Октодона в нажатия цифровых кнопок. На каждое изменение состояния джойстиков мы стали передавать посылки из 3 байт:

  1. Сканкод “Num 0”…”Num 9” — номер джойстика, статус которого передаём.
  2. Сканкод “Num 0”…”Num 4” — направление отклонения джойстика. 0 — влево, 1 — вниз, …, 4 — центральное нажатие.
  3. “Num +” в случае если было нажатие либо “Num -” в случае если отпускание.

Так, простое нажатие первого джойстика влево давало нам последовательность “00+”, отпускание — “00-”. Не отпуская один джойстик, возможно отклонять второй — так возможно кодировать одновременные нажатия нескольких кнопок, что нам было весьма необходимо для Shift-режима.Однако, стояла ещё задача каким-то образом взять переданные сканкоды. API совокупности их игнорировало, исходя из этого было нужно лезть глубже. К нашему великому счастью, Android — это *nix, в этот самый момент всё — файл.

Необходимый файл был в /dev/input и в зависимости от размещения звёзд на небе именовался либо event7, либо event8. Доступ к нему был лишь у root, исходя из этого устройство пришлось-таки рутовать, но этим всё и ограничилось — обновление firmware не пригодилась. Само применение root в Android — занимательная задачка, поскольку какого-либо метода взять соответствующие права через API нет (либо нам не удалось отыскать).

Исходя из этого делаем всё прямо через терминал:Process root = Runtime.getRuntime().exec(&как следует;su); // запускаем команду su DataOutputStream на данный момент = new DataOutputStream(root.getOutputStream()); shellStream.writeBytes(&на данный момент;cat /dev/input/event7 cat /dev/input/event8 ); // запускаем в бэкграунде две команды, копирующие в терминал всё, что отправит устройство InputStream inputStream = root.getInputStream(); InputStream errorStream = root.getErrorStream();// читаем 16-байтные эти от устройства byte[] buf = new byte[16]; if (inputStream.available() 15) { int data = inputStream.read(buf, 0, 16); }Прототип, трудившийся таким методом, просуществовал продолжительное время, прошёл множество выставок, и жив и поныне. Со временем код облагородился, и имена файлов устройств вместо хардкода стали задаваться через конфиг-файл.Ну а дальше настал золотой век.

Для Galaxy S2 вышел 4-й Android, а к нам приехали заказанные Teensy 2.0. Стыковка созданного на базе нового контроллера Raw HID устройства с показавшимся в новой ОС USB Host API прошла так гладко, что в рамки данного очерка, призванного расказывать о проблемах, совсем не укладывается. Сбылась давешняя мечта, Октодон смог трудиться на “стоковом” смартфоне без необходимости делать с ним что бы то ни было.

Мы взяли возможность производить мелкосерийные образцы, каковые , и их не нужно доводить до ума напильником. Но прекрасные ответы без палок — это тема для отдельной статьи, тем более что на страницах Хабра о работе с USB Host API не рассказывалось, думается, ни при каких обстоятельствах. Так что продолжение направляться!

Случайная статья:

Jamiroquai — Deeper Underground


Похожие статьи:

Комментирование и размещение ссылок запрещено.

Обсуждение закрыто.