Предисловие: Эта статья посвящена протокольному документу Apple «Руководство по интеграции HomeKit ADK — Приложение для Обучение «Телевизоры», ориентированное на версию ADK 6.0 TV. Описывает шаги, необходимые для интеграции ТВ-версии HomeKit ADK в целевую платформу.
Этот профиль используется для управления телевизором с поддержкой AirPlay и требует AirPlay Video SDK для создания хранилища общих ключей AirPlay и примеров аутентификации программного обеспечения MFi. ADK предоставляет PAL API AirPlayTEE для обеспечения интеграции с общим хранилищем ключей AirPlay. Это позволяет хранить долгосрочный ключ Ed25519, идентификатор устройства и соединение, совместно используемое AirPlay и HomeKit, в отдельной доверенной среде выполнения. В приведенных примерах предполагается, что AirPlay Video предоставляет механизм сокетов и механизм обратного вызова, которые позволяют телевизору HomeKit взаимодействовать с AirPlay Video. Механизм связи используется для обновления конфигураций, которые HomeKit может изменить, например имени конфигурации телевизора. Образцы SDK предоставляют интерфейс для взаимодействия с телевизионными службами и функциями через командную строку. Это полезно во время разработки и тестирования.
Образец телевизора, поставляемый с этой версией HomeKit, предлагает интеграцию с AirPlay Video. HomeKit TV и AirPlay Video используют один и тот же долгосрочный ключ Ed25519, идентификатор устройства и сопряжение, что делает эти две службы одним и тем же аксессуаром. Ed25519 Долгосрочные ключи и пары должны храниться в криптографически защищенном хранилище. Для одновременного доступа к этим секретам требуется синхронизация между AirPlay Video и HomeKit. Следующие ресурсы связаны с профилями ТВ:
Обратите внимание, что ключи сопряжения видео AirPlay и HomeKit не настраиваются статически. Вместо этого они генерируются/обмениваются при использовании вложений.
Интерфейс HAPPlatformAirPlayTEE позволяет поставщикам подключать доверенные среды выполнения к приложениям HomeKit. Индекс сопряжения должен быть стабильным во время работы вложения. В предоставленной реализации интерфейс AirPlayTEE использует API хранилища общих ключей AirPlay для чтения и записи в хранилище общих ключей AirPlay.
Приложение ТВ использует следующий интерфейс для настройки и управления видео AirPlay: 1. Настраиваемые свойства видео AirPlay:
2. Управляйте видеооперациями AirPlay:
Этот интерфейс представлен в HirPlay.h, отображается на стороне HomeKit и реализован в AirPlay как механизм связи сокетов.
Приложение ТВ использует следующий интерфейс для уведомлений и ответов между HomeKit и воспроизведением видео: 1. Уведомления из AirPlay Video в HomeKit
HomeKit использует API MFiServerTEETask, поставляемый как часть AirPlay Video SDK, для аутентификации программного обеспечения. Соответствующие ключи MFi, используемые для аутентификации программного обеспечения, и секреты FairPray, используемые для DRM, специфичны для AirPlay и не требуют синхронизации с использованием интерфейса SharedKeyStore.
HomeKit включается в процесс воспроизведения, а не запускается отдельно. AirPlay отвечает за создание основного потока HomeKit ADK и управление им. Для этого необходимо создать ADK как библиотеку, а не как отдельное приложение. При запуске make используйте «статическую» или «общую» цель для создания необходимых библиотек.
Для аксессуаров с дисплеем код настройки генерируется постоянно и меняется каждые 5 минут или после каждой попытки сопряжения.
В примере телевизора используется режим связи сокета AirPlay для отправки обновленного QR-кода в AirPlay.
HomeKit опирается на сертификацию программного обеспечения, предоставляемую как часть AirPlay Video SDK. Соответствующие ключи MFi, используемые для аутентификации программного обеспечения, и секреты FairPray, используемые для DRM, специфичны для AirPlay и не требуют синхронизации с использованием интерфейса SharedKeyStore.
При использовании профилей ТВ можно отключить определенные функции ADK. При использовании примера Makefile это можно сделать с помощью опции сборки «profile=tv», что приведет к отключению следующих функций в HAP и PAL:
Эти функции можно безопасно повторно включить по отдельности, если этого требует аксессуар. Например, некоторые аксессуары могут быть сопряжены с помощью NFC.
Начиная с ADK 3.0, ADK теперь будет просто выступать в качестве клиента для интерфейса платформы хранения общих ключей AirPlay. Это позволяет интегрировать общее хранилище ключей AirPlay в аппаратную доверенную среду выполнения. Предполагается, что поставщик использует функциональность пользовательского интерфейса HomeKit, предоставляемую AirPlay Video.
Миграция контролируется функцией Import Legacy Shared KeyStoreFormat, определенной в ADK/Applications/Television/ImportLegacySharedKeyStoreFormat.c и вызываемой в App.c. Предположим, что HomeKit ADK для телевизора скомпилирован с параметрами -DHAVE_AIRPLAY_TEE=1 и -DHAP_FEATURE_KEY_EXPORT=1. Если текущая версия HomeKit ADK до обновления уже была версии 3.0 или выше, миграция не требуется. Вызов в App.c, который импортирует устаревший формат хранения общих ключей, можно закомментировать.
HomeKit ADK для телевизоров включает модуль PAL, который понимает формат связки ключей общего хранилища ключей AirPlay и может переносить данные в хранилище ключей-значений HomeKit.
В примере с телевизором реализован следующий процесс миграции:
Уведомление: 8. В приведенном примере не переносятся пары, принадлежащие AirPlay. 9. • Сохраните хранилище значений для платформы HAP в ADK 2.1 или ADK 2.2. 10. • Чтобы миграция прошла успешно, любые изменения и адаптации, внесенные в API модуля, должны быть интегрированы в общее хранилище ключей платформы HAP. Если импорт формата хранения общих ключей Home не удался, 11. •Выпуск HomeKit ADK будет прекращен. При перезапуске приложение повторит процесс миграции.
Raspberry Pi можно использовать для отображения аксессуара для телевизора. В этом разделе описаны шаги, необходимые для создания и запуска демонстрационного видеоприложения AirPlay со встроенным профилем ADK TV на Raspberry Pi.
Как создать демо-версию Air Play со встроенным ADK с помощью Docker
make TARGET=Raspi PROFILE=Television HOMEKITSTORE_DIR=“/home/pi/.HomeKitStore" stati
make TARGET=RaspiEmu shell
cd ./External/AirplaySDK/src/AirPlaySDK
make -C PlatformPOSIX debug=1 stub=1 os=linux adk=1 -j8 platform=raspi shared=0
ADK_ROOT={PATH_TO_ADK} all
/Tools/install.sh \
-d raspi \
-a External/AirplayVideoSDK/src/AirPlaySDK/AirPlaySDK/build/Debug-linux/airplaydemo \
-n raspberrypi \
-p raspberry \
-i \
-k
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:.
./airplaydemo —config {path to Airplay video config.ini file}
В этом разделе будут описаны шаги, необходимые для создания и запуска демонстрационного видеоприложения AirPlay со встроенным профилем ADK TV в Ubuntu (рекомендуется версия 18.04).
Как создать демонстрационную версию воспроизведения и интегрировать ADK
target=linux-profile=tv-static
cd {PATH_TO_AIRPLAY}
make -C PlatformPOSIX debug=1 stub=1 os=linux adk=1 -j8 ADK_ROOT={PATH_TO_ADK}
shared=0 all
./Tools/provision_raspi.sh --category 31 --display --product-num E3644573 --setup-code
111-22-333 ~/.HomeKitStore
{PATH_TO_AIRPLAY}/build/Debug-linux/airplaydemo —config {path to Airplay video config.ini file}
В этом разделе описаны шаги, необходимые для создания примера приложения TV на Raspberry Pi без воспроизведения. Это будет иметь ограниченную функциональность, но может помочь в отладке самого кода HomeKit.
Как создать телевизионное приложение
make TARGET=Raspi USE_DISPLAY=1 apps
./Tools/install.sh \
-d raspi \
-a Output/Raspi-armv6k-unknown-linux-gnueabihf/Debug/IP/Applications/Television.OpenSSL\
-n raspberrypi \
-p raspberry \
-i \
-k
./Television.OpenSSL
В этом разделе описаны дополнительные параметры компиляции ADK, поддерживаемые примером приложения TV. Для изменения поведения приложения доступны следующие параметры. ADK предлагает варианты:
Демонстрационная реализация на основе реализации видео AirPlay MFiServerTEETask, представленной в PAL/POSIX/HAPPlatformMFiSWAuth.c.
Чтобы скомпилировать пример вложения TV с включенной аутентификацией на основе сертификатов, используйте следующую команду:
make TARGET=Raspi PROFILE=Television apps
Сделать target=Профиль Raspi=ТВ-приложение
ADK не поставляется с сертификатом испытаний.
Следующий PALAPi обеспечивает интеграцию HomeKit в общее хранилище ключей AirPlay:
• HAPPlatformAirPlayTEEGetDeviceID • HAPPlatformAirPlayTEESignBytes • HAPPlatformAirPlayTEEGetLTPK • HAPPlatformAirPlayTEEPairingAdd • HAPPlatformAirPlayTEEPairingSetPermissions • HAPPlatformAirPlayTEEPairingRead • HAPPlatformAirPlayTEEPairingRemove • HAPPlatformAirPlayTEEPairingsEnumerateCallback • HAPPlatformAirPlayTEEResetPairings • HAPPlatformAirPlay
Для интеграции см. файлы PAL/POSIX/hAPARPRAyTEE.h и PAL/PAR/HAPARPLayTEE.c.
Примечание. Если доступ к базовому TEE медленный, можно кэшировать пару, Ed25519 LTPK и идентификатор устройства в интерфейсе AirPlayTEE в формате платформы HAP. Предоставленная реализация уже включает механизм кэширования парных индексов.
HomeKit SDK предоставляет механизм видеоразъемов AirPlay. Для связи с AirPlay Video он использует сокет локальной файловой системы (/tmp/AirPlayControllers). Сокеты файловой системы можно настроить, установив определение AIRPLAY2_CONTROLLER_SOCKET_PATH в телевизоре и AirPraySDK. Серверная часть видео AirPlay реализована в контроллере AirPlay. AirPlayControllerClient.{c/h}, клиент реализован в ТВ-приложении в AirPlay.c. Приложение TV также реализует простую реализацию локального тестирования. Если платформа не поддерживает сокеты файловой системы, эту реализацию можно использовать для предоставления сетевых сокетов.
Механизм сокетов использует простые сообщения TLV8 для связи без необходимости аутентификации. Необходимо следить за тем, чтобы к розетке было подключено только приложение ТВ.
Доступны две службы настройки пробуждения, но одновременно на аксессуаре можно включить только одну. Службу пользовательской настройки пробуждения можно отключить, установив USE_CUSTOM_LPM=0 в файле build/makkefile8.5.
Службу настройки пробуждения в локальной/беспроводной локальной сети можно включить, отключив пользовательскую конфигурацию пробуждения (см. Раздел 8.4) и установив USE_WOLAN_LPM = 1 в файле сборки/создания.
Подвести итог Функция режима пониженного энергопотребления LAN/No Wireless LAN упрощает внедрение и интеграцию ADK. Режим низкого энергопотребления для IP-аксессуаров, таких как телевизоры. Эту функцию можно использовать с дополнительным агентом сна или без него.
Чтобы включить эту функцию, ADK предоставляет:
ПРИМЕЧАНИЕ. Поставщик несет ответственность за перевод аксессуара в режим низкого энергопотребления (LPM). Традиционно помещение устройства в LPM означало, что активна только его сетевая карта в поисках волшебного пакета (который его разбудит).
Пожалуйста, прочтите спецификацию HAP для получения подробной информации о поддерживаемых функциях конфигурации сна, в которой приведены инструкции по настройке параметров локальной сети/беспроводной локальной сети на аксессуаре.
A Bonjour Sleep Proxy acts as the accessory’s proxy when it’s in low power state and responds to all the requests intended for the accessory after successful registration of the accessory. This also includes responding to the mDNS requests which allows the accessory to stay in low power state and suspend its network activities while tricking other devices in the network that it’s still active and reachable. The BSP can wake up the suspended accessory by sending a magic packet when a connection/request is targeted for one of the services the accessory has registered with the BSP. HomeKit resident controllers such as ATVs and HomePods offer BSPs by default and can manage the suspended IP accessories. The BSP is also an open standard that is implemented on other devices like routers.
Агент бонусного сна действует как прокси-сервер для аксессуара, когда аксессуар находится в состоянии низкого энергопотребления, и отвечает на все запросы после успешной регистрации аксессуара. Это также включает в себя ответ на запросы mDNS, что позволяет аксессуару оставаться в состоянии низкого энергопотребления и приостанавливать свою сетевую активность, одновременно обманывая другие устройства в сети, убеждая их, что он все еще активен и доступен. BSP может активировать ожидающее вложение, отправив «магический пакет» при подключении/запросе услуги, зарегистрированной для вложения. Резидентные контроллеры HomeKit, такие как квадроциклы и HomePods, по умолчанию предоставляют bsp и могут управлять ожидающими IP-аксессуарами. BSP также является открытым стандартом, который может быть реализован на маршрутизаторах другими устройствами.
1. Включите режим пониженного энергопотребления на аксессуарах.
2. Выбор времени ввода LPN зависит от реализации поставщика. Если необходимо перейти в режим низкого энергопотребления, обновите рабочее состояние аксессуара, находящегося в спящем режиме, и вызовите предусмотренную функцию HAP (вход режима низкого энергопотребления ()), прежде чем переходить в режим низкого энергопотребления. Это закроет все открытые сеансы TCP и обновит записи Bonjour, чтобы использовать номер пробуждения (w#) вместо номера конфигурации (c#).
3. Когда аксессуар выйдет из режима пониженного энергопотребления, обновите рабочее состояние находящегося в спящем режиме аксессуара и вызовите предоставленную функцию HAP (()). Это обновит запись Bonjour, чтобы использовать номер конфигурации (c#) вместо номера пробуждения (w#).
4. Необязательно: зарегистрируйтесь в BSP, прежде чем переводить аксессуар в режим пониженного энергопотребления. Состояние гибернации может взаимодействовать с обнаружением службы на основе mDNSRanperder через сокет управления режимом низкого энергопотребления AF_UNIX, тем самым передавая зарегистрированные службы вложений на прокси-сервер гибернации Bonjour в локальной сети.
Чтобы включить имитацию режима низкого энергопотребления Raspberry Pi, установите USE_WOLAN_LPM = 1, USE_WOLAN_SIMULATION = 1 и HAP_TESTING = 1 в файле сборки/производства. В целях тестирования мы предоставляем симуляцию управления питанием на основе брандмауэра для Raspberry Pi.
Это не предназначено для использования в реальных развертываниях. Эта реализация на самом деле не реализует настоящий API управления питанием. Вместо этого состояние сна моделируется путем установки правила брандмауэра с использованием сетевого фильтра, который блокирует весь трафик ARP и IP во время сна. Таким образом, реализация не может полагаться на стандартное поведение сети для повторного определения IP-адреса после пробуждения, поэтому она отправляет пакеты ARP и NDP NA каждый раз, когда имитирует пробуждение.
Поддержка Wake-on-LAN также моделируется с использованием сокета прослушивателя, который сканирует магические пакеты WoL, отправленные с использованием неофициального эфирного типа WoL 0x0842. Другие пакеты WoL не обрабатываются эмуляцией, хотя реальное оборудование поддерживает другие пакеты.
Имитированное состояние сна передается службе обнаружения на основе mDNSRappender через сокет управления режимом пониженного энергопотребления AF_UNIX. Это позволяет нашим службам регистрации оставаться доступными в сети во время сна, передавая их на дополнительный спящий прокси-сервер в локальной сети. Когда клиент пытается подключиться к нашей рекламируемой службе DNS-SD, дополнительный спящий агент отправляет волшебный пакет, чтобы разбудить нас.
Обратите внимание, что пробуждение может происходить и по другим причинам (например, когда BSP находится в автономном режиме). В этом случае приложение несет ответственность за повторный вход в режим пониженного энергопотребления, например, за некоторое ожидание, чтобы проверить, подключается ли клиент к соответствующей рекламной службе после пробуждения. Что нас будит, можно определить только с помощью такой эвристики.
1. Зарегистрируйте обратный вызов для уведомления приложения об изменениях состояния питания.
В этом случае обратный вызов предназначен для обработки изменившегося состояния сна диспетчера электропитания.
//Наблюдаем за менеджером питания HAPPlatformPowerManagerDelegate Power Manager Delegate (делегат по управлению питанием, делегат по управлению питанием); powerManagerDelegate.handleSleepStateChanged=Обработка изменения состояния сна диспетчера питания;
2. Чтобы уведомить диспетчера питания, аксессуар должен перейти в спящий режим (поддерживает симуляцию Raspberry Pi LPM). HAPPlatformPowerManagerSleep(accessoryConfiguration.powerManager); //После вызова этой функции будет запущена обработка изменений состояния сна диспетчера электропитания (зарегистрированный агент для состояния диспетчера электропитания).
3. Уведомите диспетчер питания аксессуаров о переходе в спящий режим (введите LPM). Вызовите зарегистрированного делегата, чтобы уведомить об изменениях состояния питания аксессуара для обработки изменений состояния сна диспетчера питания. Состояние сна будет «kHAPPlatformPowerManagerSleepState_EnteringSleep».
Используя этот обратный вызов, ADK может предотвратить переход аксессуара в спящий режим до тех пор, пока мы не выполним все необходимые действия по очистке, вызвав функцию HAPPlatformPowerManagerSetPreventSleep, предоставляемую ADK. Эта функция переведет телевизор в неактивный режим, закроет все открытые сеансы TCP и зарегистрирует Bonjour. text Обновлено использование номера конфигурации (c#) на номер пробуждения (w#). Все остальные виды очистки принадлежностей должны выполняться поставщиком.
4. Диспетчер электропитания уведомляет аксессуар о том, что он начал выходить из режима сна (выход из LPM).
SleepStateChange() вызывается. Состояние сна будет «kHAPPlatformPowerManagerSleepState_Awake».
Используя этот обратный вызов, состояние рабочего состояния спящего режима приложения обновляется до «Настроено». Функциональность, предоставляемая предоставленным ADK, заключается в том, что () обновит дополнительную текстовую запись с использования номера пробуждения (w#) на номер конфигурации (c#). Все другие пробуждения, специфичные для аксессуаров, должны быть реализованы поставщиком.
5. Аксессуар уведомляет диспетчер электропитания о том, что пришло время пробуждения (выход из LPM).
Это делается при необходимости путем вызова функции моделирования LPM Raspberry Pi HAPPlatformPowerManagerExitSleep. Примером этого является использование пульта дистанционного управления для включения телевизора.
Следующие инструкции по интеграции являются ключом к успешной реализации ADK, использующей ТВ-архивы:
1. Остановите работу HomeKit. 2. Остановите воспроизведение видео. 3. Сбросьте сопряжение видео для воспроизведения в режиме Air Play. 4. Сбросьте идентификатор видео AirPlay (т. е. удалите kSharedKeyStoreLocalIdentifier, kSharedKeyStoreLocalPublicKey и kSharedKeyStoreLocalPrivateKey из хранилища общих ключей). 5. Сброс HomeKit (HAPRestoreFactorySettings, домен покупки хранилища ключей и значений платформы, HAPRestoreFactorySettings, восстановление настроек компонента платформы). 6. Начните воспроизведение видео. 7. Неверный триггер kAirPlayProperty_HomeKitAccessControlEnabled. 8. Запустите Хоум Кит.
Пользователи могут изменить название несопряженных аксессуаров на телевизоре, и такие изменения имени должны быть отражены в Bonjour. В ADK перед первым запуском сервера прикрепления установите для атрибута name структуры HAPAccesory новое значение.
static const HAPAccessory accessory = {
.aid = 1,
.category = kHAPAccessoryCategory_Televisions,
.name = "Acme Television", // <<- This is the Bonjour name, and also what
is put as Name into Accessory Information Service. Once HAP is running it is
immutable.
.manufacturer = "Acme",
.model = "Television1,1",
.serialNumber = "099DB48E9E28",
.firmwareVersion = "1",
.hardwareVersion = "1",
.services = (const HAPService *const[]) {
&accessoryInformationService,
&hapProtocolInformationService,
&pairingService,
&televisionService,
&inputSourceHomeScreenService,
&inputSourceTunerService,
&inputSourceHDMI0Service,
&inputSourceHDMI1Service,
&inputSourceHDMI2Service,
&inputSourceCompositeVideoService,
&inputSourceSVideoService,
&inputSourceComponentVideoService,
&speakerService,
µphoneService,
&occupancySensorService,
&lightSensorService,
&accessControlService,
NULL
},
.callbacks = {
.identify = IdentifyAccessory
}
}
После первого запуска HAPAncseroryServer для данного вложения его имя больше нельзя изменять в соответствии с требованиями спецификации HAP, указанными в разделе 9.1. Информация о вложениях. Имена вложений недоступны даже во время удаления, перезапуска, обновления прошивки и сброса настроек. . Что касается ADK, технически возможно установить новое имя при остановке вторичного сервера (например, вы можете остановить сервер HomeKit, изменить имя и перезапустить сервер HomeKit).