Меню
andipanda.dev

Від проблем із Carlinkit до власного CarPlay

Від завершення CaRadio до нової ідеї

У попередніх статтях я докладно розповідав про розробку власної автомобільної магнітоли CaRadio. Поступово проект дійшов до стану, коли ним уже можна було повноцінно користуватися в автомобілі.

Після тривалої поїздки, під час якої я випробовував магнітолу в реальних умовах, залишалося виправити кілька недоліків. Одним із них була робота зі звуком під час використання CarPlay через адаптер Carlinkit.

Проблема полягала в обробці навігаційних підказок.

Коли навігатор починав відтворювати голосову підказку, CaRadio отримувала відповідну подію та могла зменшити гучність музики. Але визначити момент завершення підказки мені так і не вдалося.

У результаті музика або поверталася до попередньої гучності надто рано, або залишалася приглушеною довше, ніж потрібно.

Довелося використати обхідне рішення з часовими затримками. Після кількох експериментів вдалося підібрати варіант, який досить добре працював на практиці.

На цьому перша версія CaRadio була фактично завершена.

Магнітола працювала, CarPlay підключався, музика відтворювалася, навігація функціонувала. Тим більше, ця реалізація продовжує працювати й досі.

Але я чудово розумів, що проблему вирішено не зовсім правильно. Замість обробки реальної події завершення навігаційної підказки програма просто очікувала певний час.

Саме цей невеликий технічний компроміс зрештою привів мене до абсолютно нового напряму розробки.

Спроба розібратися з протоколом Carlinkit

Хоча перша версія CaRadio вже працювала, проблема з визначенням завершення навігаційних підказок не давала мені спокою. Я вирішив повернутися до вивчення протоколу Carlinkit і спробувати знайти правильне рішення.

На той момент я вже досить добре розібрався в обміні даними між CaRadio та адаптером. Однак залишалися питання щодо деяких команд і подій. Можливо, Carlinkit передавав необхідну інформацію, але я просто не знав, як її інтерпретувати. Не виключав я й того, що сам адаптер не надавав потрібних подій.

Я знову почав шукати документацію, вихідний код і результати реверс-інжинірингу. Цього разу мене цікавили не лише команди обміну з Carlinkit, а й внутрішня робота самого адаптера — зокрема, його взаємодія з iPhone.

Поступово пошуки вийшли за межі початкового завдання. Я дедалі частіше знаходив матеріали, присвячені нативному підключенню CarPlay без використання готових адаптерів. Інформації було небагато, вона траплялася окремими фрагментами, але саме тоді я знову звернув увагу на апаратну автентифікацію MFi.

У певний момент у мене виникло запитання: якщо розібратися в механізмі автентифікації та обміні даними безпосередньо з iPhone, чи вдасться взагалі обійтися без Carlinkit?

MFi та апаратна автентифікація

У процесі вивчення CarPlay я знову натрапив на згадки про MFi — програму Apple Made for iPhone.

Для певних сценаріїв взаємодії з пристроями Apple використовується спеціальний чип автентифікації. Він дає змогу виконувати необхідні криптографічні операції, не розкриваючи закриті ключі безпосередньо програмному забезпеченню.

Ідея використати такий чіп для власної реалізації CarPlay здавалася цікавою.

Але виникало цілком очевидне запитання: де його взяти?

Окремі мікросхеми MFi не належать до звичайних компонентів, які можна просто вибрати в каталозі електронних деталей і замовити в будь-якій кількості.

Проте в мене вже був адаптер Carlinkit U2W Mini.

І я вирішив подивитися, що знаходиться всередині.

Розбирання Carlinkit U2W Mini

Після розбирання адаптера я почав вивчати його плату.

Мене цікавили не стільки процесор і пам'ять, скільки компоненти, відповідальні за взаємодію з iPhone.

У результаті вдалося знайти необхідний чип автентифікації.

Це було важливе відкриття: тепер я мав не лише інформацію про існування подібних мікросхем, а й реальний компонент, з яким можна було експериментувати.

Однак спочатку я вирішив піти трохи іншим шляхом.

Якщо отримати доступ до операційної системи самого адаптера, можна було б вивчити його програмне забезпечення та, можливо, значно швидше розібратися з протоколом.

Спроба отримати доступ через UART

На платі U2W Mini я знайшов інтерфейс UART і спробував використати його для підключення до адаптера.

Частину завдання вдалося вирішити досить швидко.

Адаптер передавав дані через послідовний інтерфейс, і я міг спостерігати його вивід.

Але повноцінного двостороннього з'єднання отримати не вдалося.

Попри те, що дані від адаптера надходили, надіслані йому команди не давали очікуваного результату.

Я намагався розібратися в причинах, але швидко отримати доступ до операційної системи не вдалося.

Продовжувати витрачати час в цьому напрямку не хотілося, тому я тимчасово відклав експерименти з UART.

Утім, розбирання адаптера вже принесло результат: я знав, де знаходиться MFi-чип, і міг повернутися до нього пізніше.

Пошук інформації про Native CarPlay

Після невдалої спроби отримати доступ до операційної системи U2W Mini я продовжив шукати інформацію.

Але тепер мене цікавив вже не лише протокол Carlinkit.

Поступово з'явилася інша ідея: а чи обов'язково взагалі використовувати Carlinkit?

Адже якщо розібратися в механізмах підключення iPhone та отримати доступ до необхідного чипа автентифікації, теоретично можна спробувати реалізувати CarPlay безпосередньо на Raspberry Pi.

Це означало б, що готовий адаптер більше не потрібен як посередник між iPhone та моєю магнітолою.

Проблема полягала в нестачі інформації.

У відкритому доступі траплялися окремі фрагменти документації, обговорення протоколів, приклади взаємодії з MFi та деякі результати досліджень.

Але зібрати з цього повноцінну робочу реалізацію було далеко не просто.

Я витратив чимало часу, поступово збираючи інформацію буквально по крихтах.

Проте знайдені матеріали давали підстави припускати, що реалізація Native CarPlay на Raspberry Pi цілком можлива.

І тоді я знову згадав про проєкт LIVI.

Несподіване відкриття в LIVI

З LIVI я був знайомий ще з часів попередніх експериментів із CarPlay.

Цей проект уже допомагав мені розібратися в деяких особливостях взаємодії з адаптерами та став одним із джерел інформації під час розробки CaRadio.

Вирішивши подивитися, що змінилося з моменту мого останнього знайомства з його вихідним кодом, я знову відкрив репозиторій.

І виявив те, чого зовсім не очікував.

У LIVI вже з'явилася реалізація Native CarPlay.

Причому відповідні зміни були зовсім свіжими. Наскільки я міг судити з історії проєкту, вони з'явилися буквально протягом кількох тижнів, поки я займався випробуваннями CaRadio та подальшими доопрацюваннями.

Вийшла доволі кумедна ситуація.

Я витратив багато часу на пошук розрізненої інформації, вивчав можливі способи автентифікації, розбирав Carlinkit і намагався отримати доступ до його операційної системи.

А тим часом у вже знайомому мені проекті з'явилася реалізація саме того, до чого я поступово дійшов самостійно.

Звісно, це не означало, що тепер достатньо скопіювати кілька файлів і отримати повністю робочу систему.

Потрібно було розібратися у вихідному коді, підключити власне обладнання, перевірити взаємодію з iPhone та адаптувати необхідні компоненти під свої завдання.

Але тепер у мене була значно конкретніша відправна точка.

Від ідеї до нового проєкту

На цьому етапі початкове завдання вже помітно змінилося. Усе починалося зі спроби виправити обробку навігаційних підказок у CaRadio, але тепер переді мною відкривалася можливість спробувати реалізувати власне підключення CarPlay без використання готового адаптера.

Після виявлення реалізації Native CarPlay у LIVI я вирішив почати з апаратної частини. Необхідний MFi-чип уже був знайдений на платі розібраного Carlinkit U2W Mini. Залишалося розібратися, як підключити його до Raspberry Pi.

На щастя, у мікросхеми виявилося зовсім небагато виводів. Визначити живлення вдалося досить швидко, а вивчення документації на процесор V851 дозволило остаточно переконатися, які контакти використовуються для шини I²C.

Я припаяв до потрібних контактів тонкі дроти та підключив їх до шини I²C Raspberry Pi 3B+.

Потім запустив сканування шини.

І практично відразу побачив те, на що розраховував, — адресу MFi-чипа.

Це був невеликий, але дуже важливий результат. Тепер мікросхема, витягнута з готового адаптера, визначалася Raspberry Pi як окремий I²C-пристрій. Наступним кроком потрібно було розібратися в командах автентифікації та перевірити, чи вдасться використати її для безпосереднього підключення iPhone.

Саме з цього моменту почалася практична робота над новим проектом, який згодом отримав назву CaRaBack — від CaRadio та Backend.

Але виявити MFi-чип на шині було лише першим кроком. Попереду залишалося значно складніше завдання — змусити iPhone встановити з'єднання з моєю власною реалізацією CarPlay.

Про це йтиметься в наступній статті.