Grabduck

История одного «очень китайского» телефона

:

Путь от “несвяти с сетей” и “спаритьБлютуф” до человеческого телефона

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

Так было и со мной, когда примерно два года назад я увидел на очередном китайском сайте смартфон с gps, usb-host’ом, двумя камерами и прочими плюшками за смешные деньги. В тот момент, само словосочетание “китайский телефон” должно было остановить меня, но я уже вписывал пароль от PayPal и скоро эта “прелесть” попала мне в руки…

Я чувствовал, что я обманул систему, ведь у меня в руках “телефон со всеми наворотами”, пусть немного китайский, но ведь за копейки.

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

Не могли не радовать такие пункты меню, как “Блютуф”, “Уст. Т.ф”, “Непр.к. Со.” и прочие сокращения, истинные значения которых можно было узнать лишь по картинкам. В дополнение, уже в районе меню третьего уровня (а разработчики не побрезговали и вложенностью меню до 9-ого уровня) картинки исчезли (не считая “ценных” номеров пунктов меню красного цвета) и вместе с ними исчезло и понимание процесса (что делает меню “вкл. UI эдиции” можно угадывать довольно долго). Сразу отмечу, что на телефоне была возможность выбрать язык и что английская версия намного лучше русской, что весь перевод хранится в txt файле, который можно было бы подредактировать и избавиться хоть от части этого уродства. При желании, можно было даже перерисовать некоторые картинки (например, те, на которых особенно чётко были видны артефакты JPEG), которые представляли собой кучу файлов (около 200) в папке “\Windows\”. Дело было не в конкретном пункте меню и не какой-то определённой части интерфейса. Дело было в непроходящем ощущении того, что я совершил огромную глупость, заплатив за ЭТО деньги. Приведу ещё несколько примеров, чтобы был лучше понятен мой восторг в тот момент:

В защиту телефона могу добавить то, что даже когда у него что-то не получалось, он делал это так смешно, что было трудно на него злиться. Например, при ошибке подключения к WiFi сети, он выдавал “неудачно содениниять”. Как вообще можно злиться на предмет, который очень старается “удачно посодениниять”?!

Когда я закончил осматривать все прелести дизайна и перевода, с другого телефона был сделан первый звонок для проверки связи… Телефон дозвонился и раздался первый гудок, но чудо инженерной мысли из поднебесной предательски молчало. За первым гудком последовал второй, а за ним и третий… И только тогда китайский телефон осознал, что звонят именно на него и отобразил очередное окно жутковатого вида. Следует отметить, что за всё время моих попыток получить от китайского телефона (а именно от китайской программы) адекватное время отклика, это был один из лучших показателей. Бывали ситуации, когда между первой реакцией китайской продукции и сообщением второго телефона “абонент не отвечает” проходило всего 2-3 секунды.

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

Моим спасением могла стать “более свежая” прошивка для телефона, в которой разработчики могли уже и исправить многие проблемы. К моему удивлению, небезызвестный поисковик сразу выдал сайт и форум производителя. По правде говоря, я не ждал не только того, что у них будет свой сайт, но особенно того, что там будут новые прошивки! Оттуда была удачно получена последняя версия прошивки, но это не изменило ровным счётом ничего. Стало понятно одно: если эта проблема не исправлена, значит либо она только у меня, либо это проблема железа и с ней ничего не сделаешь, либо кривые руки разработчиков не позволяют им нормально среагировать на сообщение от модема. За неимением других вариантов, вся надежда была на последний вариант, и я решил попробовать написать свою версию пользовательского интерфейса для очень китайского телефона…

Сначала, было необходимо отключить тот ужас, на который я любовался с момента включения телефона. Для этого телефон был подключен к компьютеру, и был запущен Windows CE Remote Process Viewer.

Процесс имел гордое название “PhoneUI.exe”, работал в 18 потоков и подгружал небольшую армию библиотек. В тот момент меня интересовала только одна вещь — в чём причина такой разницы между дозвоном и нотификацией, а для этого нужно было попробовать “пообщаться” с модемом. Позже выяснилось, что в телефоне модем был “блуждающим” и даже родной PhoneUI.exe пробовал подключиться к модему по принципу “может ты модем?” в следующем порядке: “GSM1:”, “VCP1:”, “VCP2:”, “VCP3:”, “COM1:”, “COM3:”.

На скорую руку набросал небольшую программку, которая подключалась к модему, посылала команду и ожидала ответа. Программа была запущена на телефоне, но модем не ответил — программа встала на этапе чтения ответа от модема. Не буду вас утомлять описанием того, как я искал кто-же модем в системе, как перерыл реестр с помощью Windows CE Remote Registry Editor (что имело хоть небольшой КПД, т.к. я убрал с автозагрузки PhoneUI.exe). Когда искать надоело, я взялся за дизассемблер и стал ковырять PhoneUI.exe с целью быстренько убедиться в том, что используется стандартная связка Windows API функций: CreateFile / WriteFile / ReadFile / CloseHandle. То, что программа содержала отладочную информацию, меня не слишком удивило и оказалось очень даже кстати:

Чтобы убедиться, что китайцы не выдумали особого способа общения с модемом, я запустил поиск по “AT+”. Первым совпадением было “%xAT+CGATT=1\r”. Передача данных модему происходила вызовом Windows API функции WriteFile, что было предсказуемо, но я немного удивился тому, что моя программа не сработала.

Позже выяснилось, что это была ветка программы, которая выполняется только в “особом случае” и что такой метод отправки команд модему слишком казуальный для креативных разработчиков данного устройства. Я снова упускаю несколько дней “безрезультатного потыка” в разные места телефона и перебор всех возможных параметров и комбинаций настроек. Дойдя до очередного исступления от того, что PhoneUI.exe удачно общается с модемом, а моя программа не может получить ответа и на одну команду, я решил взяться за дизассемблирование серьёзнее и не ограничиваться поиском первой попавшейся AT команды.

В этот момент, учитывая, что телефон стоил денег и я уже затратил на него немало времени, я понимал, что дешевле было купить новый iPhone, но теперь это уже было дело принципа.

Повторный поиск показал, что AT команды шлются двумя способами — первый уже был описан выше, второй — через вызов функции DeviceIoControl. Т.е. для передачи данных модему вместо WriteFile используется DeviceIoControl. На её вызов и был поставлен breakpoint, и вскоре стала понятна схема передачи команд модему.

Также стало известно, что необходим дополнительный вызов DeviceIoControl после CreateFile, чтобы активировать модем. После нескольких часов выдирания необходимых значений из PhoneUI.exe стало ясно следующее:

  1. Модем обычно расположен на “GSM1:”. Я использую слово “обычно”, т.к., если телефон на момент включения подключен к компьютеру или ему просто стало скучновато, то модем мигрирует на “VCP1:”, “VCP2:” и далее по цепочке.
  2. После CreateFile необходимо вызвать DeviceIoControl с кодом 0xf00d226c и без дополнительных параметров.
  3. Для отправки данных модему, используется DeviceIoControl с кодом 0xf00d2268, в качестве параметра передаётся строка фиксированной длины (1032 байта) из которой первые 4 байта — HANDLE, полученный после вызова CreateFile, 1024 байта — строка, содержащая AT команду(ы), и последние 4 байта — длинна строки. После пункта (2) можно использовать и WriteFile, но работает он раз через раз, поэтому использовать его я не стал.
  4. Для чтения, как обычно, используется ReadFile.

К моей радости, модем понимал основной набор AT команд и имел свой дополнительный набор команд, которые были удачно “выцеплены” из PhoneUI.exe.

Затем последовала ещё целая эпопея с контролем динамиков, вибрации и прочих элементов телефона, написание своего простенького графического интерфейса, где всё тоже не обошлось без приключений, но это уже другая история “очень китайского” телефона. Для тех, кому интересно, привожу несколько скриншотов того, что было сделано в результате (ничего особенного, просто оболочка для просмотра состояния и управления телефоном и включения / выключения основных устройств):

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

Телефон умел даже уходить, как “очень китайский телефон”:

Спасибо тем, кто сделал это чудо.