HomeKit Accessory Development Kit (ADK)

repository·master·Indexed 25 days ago

https://github.com/apple/homekitadk

An implementation of the HomeKit Accessory Protocol (HAP) for building HomeKit-compatible devices. It provides tools for silicon vendors and accessory manufacturers, including a Crypto PAL supporting OpenSSL and MbedTLS, and guidelines for non-commercial prototyping and commercial production via the MFi Program.

Tokens
8K
Snippets
21
Records
30
Agent score
83%

What's inside HomeKit ADK

  1. Overview of HomeKit Accessory Development Kit (ADK)

    master

    The HomeKit ADK is used by silicon vendors and accessory manufacturers to build HomeKit compatible devices. It implements key components of the HomeKit Accessory Protocol (HAP), focusing on security, privacy, and reliability.

    Note on Licensing:

    • Open Source ADK: Can be used by any developer to prototype non-commercial smart home accessories.
    • Commercial ADK: For commercial accessories, developers must use the commercial version available through the MFi Program.

    For more information on developing HomeKit-enabled accessories and apps, visit the Apple Developer Site.

  2. Configure Visual Studio Code for Darwin application debugging

    master

    To debug an ADK application using the visual debugger in VS Code:

    1. Create a workspace that points to the root of your ADK folder.
    2. Navigate to Debug > Open Configuration to open launch.json.
    3. Set the type field to "lldb".
    4. Set the program field to the absolute path of the application binary you wish to run.
    5. Ensure cwd is set to ${workspaceFolder} to maintain correct relative paths.
    {
        "version": "0.2.0",
        "configurations": [
            {
                "type": "lldb",
                "request": "launch",
                "name": "Debug",
                "program": "${workspaceFolder}/Output/Darwin-x86_64-apple-darwin19.0.0/Debug/IP/Applications/Lightbulb.OpenSSL",
                "args": [],
                "cwd": "${workspaceFolder"
            }
        ]
    }
  3. Implement Error Handling using HAPError and out-parameters

    master

    The project distinguishes between unexpected errors and expected conditions:

    1. Unexpected Errors: Use HAPError for exceptional circumstances (e.g., I2C communication failure, key-value store access problems). These should be bubbled up to the caller.
    2. Expected Errors: Use separate out-parameters (e.g., bool *found, bool *isSet, bool *isAvailable) for predictable conditions like a missing key or unconfigured Wi-Fi. Do not use bool *isValid to denote existence.

    Rules for callers:

    • Treat HAPError as a boolean check.
    • If a HAPError is returned, do not assume any out-parameters are valid.
    • If kHAPError_None is returned, all applicable out-parameters must contain valid values.
  4. Install VS Code extensions for Darwin visual debugging

    master

    To enable C/C++ language support and LLDB debugging in Visual Studio Code on Darwin, install the following extensions using the Command Palette (⌘+P):

    1. C/C++ Language Support: ms-vscode.cpptools
    2. LLDB Debugger: vadimcn.vscode-lldb (Note: This alternative debugger is required because LLVM no longer includes lldb-mi, which the default debugger relies on).
  5. Setup, compile, and install for Raspberry Pi

    master

    Prerequisites

    Run the SD card setup script to create the Linux+patches SD card image and the Docker build environment. Note: Docker must be running before starting. This process takes approximately one hour and requires swapping the SD card twice.

    ./Tools/raspi_sdcard_setup.sh

    Compilation

    Build for the Raspberry Pi target:

    make TARGET=Raspi all

    Note: If Docker cannot find dev-test/raspiadk-base, re-run the SD card setup and ensure the docker import completes at the end of the script.

    Installation

    Use the install.sh tool to deploy build products to your Raspberry Pi. You must provide the hostname (-n) and the SSH password (-p) configured during the initial SD card setup.

    Example installation:

    ./Tools/install.sh \
        -d raspi \
        -a Output/Raspi-armv6k-unknown-linux-gnueabihf/Debug/IP/Applications/Lightbulb.OpenSSL \
        -n raspberrypi \
        -p raspberry
    ./Tools/raspi_sdcard_setup.sh
    make TARGET=Raspi all
    ./Tools/install.sh \
        -d raspi \
        -a Output/Raspi-armv6k-unknown-linux-gnueabihf/Debug/IP/Applications/Lightbulb.OpenSSL \
        -n raspberrypi \
        -p raspberry
  6. Setup and compile for Darwin (macOS)

    master

    To develop on Darwin, ensure you have Xcode 11 and Command Line Tools for Xcode 11 installed. You must also install several dependencies via Homebrew and have Docker Desktop running (with 'Start Docker Desktop when you log in' enabled in Preferences).

    Prerequisites

    Install dependencies using Homebrew:

    brew install openssl@1.1
    brew install mbedtls --HEAD
    brew install wget
    brew install qemu
    brew install --cask docker

    Compilation and Execution

    Build the project using:

    make all

    Run the compiled application (example for Lightbulb with OpenSSL):

    ./Output/Darwin-x86_64-apple-darwin$(uname -r)/Debug/IP/Applications/Lightbulb.OpenSSL
    brew install openssl@1.1
    brew install mbedtls --HEAD
    brew install wget
    brew install qemu
    brew install --cask docker
    
    make all
    
    ./Output/Darwin-x86_64-apple-darwin$(uname -r)/Debug/IP/Applications/Lightbulb.OpenSSL
  7. Structure Header Files with HAP Standards

    master

    Header files must follow a strict layout to ensure compatibility and automated processing:

    1. Copyright notice (must be exact for scripts).
    2. Header guard (HAP_UNDERSCORED_FILE_NAME_H).
    3. extern "C" declaration.
    4. System headers (alphabetical, only in HAPBase.h or platform-specific code).
    5. Platform headers (alphabetical).
    6. HAP.h or HAPPlatform.h (alphabetical).
    7. assume_nonnull block.
    8. Header contents.
    9. End assume_nonnull block.
    10. Complete extern "C" and header guard.
    #ifndef HAP_HEADER_FILE_NAME_H
    #define HAP_HEADER_FILE_NAME_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include <system_header.h>
    #include "platform_header.h"
    #include "HAPPlatform.h"
    
    #if __has_feature(nullability)
    #pragma clang assume_nonnull begin
    #endif
    
    // Header file contents.
    
    #if __has_feature(nullability)
    #pragma clang assume_nonnull end
    #endif
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
  8. Enforce lint rules at commit time with a git pre-commit hook

    master

    To ensure all commits are properly linted, you can install a git pre-commit hook. This hook checks all staged files and will fail the commit if the linter finds issues. Note that the hook only validates and fails; it does not automatically reformat or fix issues.

    cp Tools/linters/git-hooks-pre-commit .git/hooks/pre-commit
  9. Reference Specifications in Code and Documentation

    master

    When referencing the HomeKit Accessory Protocol Specification, use a consistent format to enable easy searching:

    • Documentation blocks: Use @see or See followed by the exact PDF Title. The second line should be the Section number and exact Section Title.
    • Code comments: Use // See ... followed by the exact Section/Table details.
    • Obsolete features: Use the Doxygen @obsolete tag instead of deleting enum values.

    Example Documentation Block:

    /**
     * ...
     *
     * @see HomeKit Accessory Protocol Specification R15
     *      Section 1.2.3.4 Some Sample Section
     */