Skip to main content

Camera Firmware Update

Camera OTA updates the firmware running on a supported device's camera module. It is separate from the device's main firmware update.

The host app provides a compatible local camera firmware package. The SDK then coordinates the complete upgrade workflow: configuring the device hotspot, entering Camera OTA mode, starting a local HTTP server, sending the firmware URL to the device, transferring the package, and flashing the camera firmware. Use the stage callbacks to present the current operation, and treat the final completion handler as the authoritative upgrade result.

Animated workflow

Camera OTA delivery path

A local package moves from host-side validation through SDK orchestration to transfer, flashing, and the authoritative final result.

Host app

Validate Package

Verify integrity, camera-model compatibility, and a readable local path.

SDK + device

Configure Hotspot

Prepare the device network used by the Camera OTA workflow.

Device

Enter OTA Mode

Switch the camera module into its firmware update mode.

SDK

Connect Hotspot

Join the SSID exposed for the staged update session.

SDK

Start HTTP Server

Expose the selected local firmware package to the device.

SDK → device

Send Firmware URL

Deliver the local HTTP URL that the device will request.

Progress phase

Transfer Firmware

Serve the package while the device downloads the firmware bytes.

.transferring · 0...100
Progress phase

Flash Firmware

The camera module writes the transferred firmware. Do not interrupt.

.flashing · 0...100
Authoritative result

Final Completion

Use the final callback—not transfer progress—as the upgrade result.

Follow the final completion callback for the authoritative result.

Prerequisites

  • The device is connected and conforms to DeviceCameraOtaAPI.
  • The local firmware path is readable and the package matches the camera hardware.
  • The app can join the device hotspot, access the local network, and keep its local HTTP server available.
  • Prevent concurrent media import, camera OTA, or other hotspot workflows.

Implement with AI Assistance

Build with AI

Implement this workflow with AI

Use the official Update AIBuds Camera Firmware skill to adapt this workflow to your app.

Read and follow https://docs-aibuds.github.io/skills/update-aibuds-camera-firmware. Use it to implement Update AIBuds Camera Firmware in this iOS project and verify the result.
View official skill

API Reference

Framework

AIBuds.xcframework

Import

Swift
import AIBuds
import AIBudsFoundation

Protocol

The DeviceCameraOtaAPI protocol inherits from DeviceAPI and currently exposes one instance method for the complete Camera OTA workflow.

Instance Method

Swift
/// Start camera OTA upgrade.
///
/// - Parameters:
///   - filePath: The readable local path of the camera firmware file.
///   - configureHotspotStartingHandler: Called when hotspot configuration starts.
///   - hotspotConfigureCompletionHandler: Called when hotspot configuration completes.
///     - success: `true` if configuration succeeded; otherwise `false`.
///     - error: The failure information, or `nil` if configuration succeeded.
///   - enterCameraOtaModeStartingHandler: Called when entry into camera OTA mode starts.
///   - enterCameraOtaModeCompletedHandler: Called when entry into camera OTA mode completes.
///     - success: `true` if the device entered OTA mode; otherwise `false`.
///     - error: The failure information, or `nil` if entry succeeded.
///   - waitingForHotspotOpenHandler: Called while waiting for the device hotspot to open.
///   - connectDeviceHotspotStartingHandler: Called when connecting to the device hotspot starts.
///     - ssid: The SSID of the device hotspot.
///   - deviceHotspotConnectCompletionHandler: Called when the hotspot connection completes.
///     - success: `true` if the connection succeeded; otherwise `false`.
///     - error: The failure information, or `nil` if the connection succeeded.
///   - httpServerStartingHandler: Called when the local HTTP server is starting.
///   - httpServerStartCompletionHandler: Called when the HTTP server start attempt completes.
///     - success: `true` if the server started; otherwise `false`.
///     - error: The failure information, or `nil` if the server started.
///   - sendingFirmwareUrlHandler: Called before sending the firmware URL to the device.
///     - firmwareUrl: The local HTTP URL that will be sent.
///   - firmwareUrlSendCompletionHandler: Called when firmware URL delivery completes.
///     - success: `true` if the URL was sent; otherwise `false`.
///     - error: The failure information, or `nil` if delivery succeeded.
///   - startCompletionHandler: Called when the Camera OTA start command completes.
///     - success: `true` if the update started; otherwise `false`.
///     - error: The failure information, or `nil` if the update started.
///   - fileTransferStartedHandler: Called when firmware transfer starts.
///   - fileTransferCompletedHandler: Called when firmware transfer completes.
///   - waitingForFlashingHandler: Called while the device is preparing to flash.
///   - flashingStartedHandler: Called when firmware flashing starts.
///   - flashingCompletedHandler: Called when firmware flashing completes.
///   - phaseProgressHandler: Reports progress for transfer and flashing.
///     - phase: `.transferring` or `.flashing`.
///     - progress: The phase progress in the range `0...100`.
///   - completionHandler: Called when the complete Camera OTA workflow finishes.
///     - success: `true` if the upgrade succeeded; otherwise `false`.
///     - error: The failure information, or `nil` if the upgrade succeeded.
func startCameraOta(
    withFilePath filePath: String,
    configureHotspotStartingHandler: AIBudsCameraOtaConfigureHotspotStartingHandler?,
    hotspotConfigureCompletionHandler: AIBudsCameraOtaHotspotConfigureCompletionHandler?,
    enterCameraOtaModeStartingHandler: AIBudsEnterCameraOtaModeStartingHandler?,
    enterCameraOtaModeCompletedHandler: AIBudsEnterCameraOtaModeCompletionHandler?,
    waitingForHotspotOpenHandler: AIBudsCameraOtaStartingToWaitForHotspotOpenHandler?,
    connectDeviceHotspotStartingHandler: AIBudsCameraOtaConnectDeviceHotspotStartingHandler?,
    deviceHotspotConnectCompletionHandler: AIBudsCameraOtaDeviceHotspotConnectCompletionHandler?,
    httpServerStartingHandler: AIBudsCameraOtaHttpServerStartingHandler?,
    httpServerStartCompletionHandler: AIBudsCameraOtaHttpServerStartCompletionHandler?,
    sendingFirmwareUrlHandler: AIBudsCameraOtaSendingFirmwareUrlHandler?,
    firmwareUrlSendCompletionHandler: AIBudsCameraOtaFirmwareUrlSendCompletionHandler?,
    startCompletionHandler: AIBudsCameraOtaStartCompletionHandler?,
    fileTransferStartedHandler: AIBudsCameraOtaFileTransferStartedHandler?,
    fileTransferCompletedHandler: AIBudsCameraOtaFileTransferCompletedHandler?,
    waitingForFlashingHandler: AIBudsCameraOtaWaitingForFlashingHandler?,
    flashingStartedHandler: AIBudsCameraOtaFlashingStartedHandler?,
    flashingCompletedHandler: AIBudsCameraOtaFlashingCompletedHandler?,
    phaseProgressHandler: AIBudsCameraOtaPhaseProgressHandler?,
    completionHandler: AIBudsCameraOtaCompletionHandler?
)

See startCameraOta in the API Reference.

Return Value

This method does not return a value directly. Startup, stage transitions, progress, and the final result are delivered through the supplied handlers.

Workflow Stages

These are callback stages in the Camera OTA workflow. They are not values of CameraOtaProgressPhase.

StageRelated handlers
Configure hotspotconfigureHotspotStartingHandler, hotspotConfigureCompletionHandler
Enter Camera OTA modeenterCameraOtaModeStartingHandler, enterCameraOtaModeCompletedHandler
Connect device hotspotwaitingForHotspotOpenHandler, connectDeviceHotspotStartingHandler, deviceHotspotConnectCompletionHandler
Start local HTTP serverhttpServerStartingHandler, httpServerStartCompletionHandler
Send firmware URLsendingFirmwareUrlHandler, firmwareUrlSendCompletionHandler
Start updatestartCompletionHandler
Transfer firmwarefileTransferStartedHandler, fileTransferCompletedHandler
Prepare and flashwaitingForFlashingHandler, flashingStartedHandler, flashingCompletedHandler
FinishcompletionHandler

Progress Phases

CameraOtaProgressPhase contains exactly two public values. The progress argument is an integer from 0 through 100 for the reported phase.

SwiftObjective-CRaw valueMeaning
.transferringAIBudsCameraOtaProgressPhaseTransferring1Firmware file transfer progress.
.flashingAIBudsCameraOtaProgressPhaseFlashing2Camera firmware update progress.

Usage Examples

The examples preserve every callback exposed by the SDK Demo. Update UI on the main queue in production code.

Swift
guard let cameraOtaDevice = device as? DeviceCameraOtaAPI else {
    print("Camera OTA is not supported")
    return
}

cameraOtaDevice.startCameraOta(
    withFilePath: filePath,
    configureHotspotStartingHandler: {
        print("Configuring device hotspot")
    },
    hotspotConfigureCompletionHandler: { success, error in
        print(
            success
                ? "Hotspot configured"
                : "Hotspot configuration failed: \(error?.localizedDescription ?? "Unknown error")")
    },
    enterCameraOtaModeStartingHandler: {
        print("Entering Camera OTA mode")
    },
    enterCameraOtaModeCompletedHandler: { success, error in
        print(
            success
                ? "Camera OTA mode ready"
                : "Could not enter Camera OTA mode: \(error?.localizedDescription ?? "Unknown error")"
        )
    },
    waitingForHotspotOpenHandler: {
        print("Waiting for device hotspot")
    },
    connectDeviceHotspotStartingHandler: { ssid in
        print("Connecting to \(ssid)")
    },
    deviceHotspotConnectCompletionHandler: { success, error in
        print(
            success
                ? "Device hotspot connected"
                : "Hotspot connection failed: \(error?.localizedDescription ?? "Unknown error")")
    },
    httpServerStartingHandler: {
        print("Starting local HTTP server")
    },
    httpServerStartCompletionHandler: { success, error in
        print(
            success
                ? "HTTP server ready"
                : "HTTP server failed: \(error?.localizedDescription ?? "Unknown error")")
    },
    sendingFirmwareUrlHandler: { firmwareURL in
        print("Sending firmware URL: \(firmwareURL)")
    },
    firmwareUrlSendCompletionHandler: { success, error in
        print(
            success
                ? "Firmware URL sent"
                : "URL delivery failed: \(error?.localizedDescription ?? "Unknown error")")
    },
    startCompletionHandler: { success, error in
        print(
            success
                ? "Camera OTA started"
                : "Camera OTA could not start: \(error?.localizedDescription ?? "Unknown error")")
    },
    fileTransferStartedHandler: {
        print("Firmware transfer started")
    },
    fileTransferCompletedHandler: {
        print("Firmware transfer completed")
    },
    waitingForFlashingHandler: {
        print("Waiting for flashing")
    },
    flashingStartedHandler: {
        print("Firmware flashing started")
    },
    flashingCompletedHandler: {
        print("Firmware flashing completed")
    },
    phaseProgressHandler: { phase, progress in
        switch phase {
        case .transferring:
            print("Transfer: \(progress)%")
        case .flashing:
            print("Flashing: \(progress)%")
        }
    },
    completionHandler: { success, error in
        if success {
            print("Camera OTA completed successfully")
        } else {
            print("Camera OTA failed: \(error?.localizedDescription ?? "Unknown error")")
        }
    }
)

Error Handling

Camera OTA errors use AIBudsSDK.CameraOtaErrorDomain and SdkCameraOtaErrorCode. The public enum covers local file validation, network/hotspot failures, task lifecycle failures, OTA-mode entry failures, and firmware-URL delivery failures.

CodesTypical condition
unknown, networkRequestFailed, networkTimeoutThe SDK cannot classify the error more narrowly or network activity fails.
cameraOtaFileNotFound, invalidCameraOtaFile, cameraOtaTaskCreateFailedDueToFileNotFoundThe selected local firmware path is missing or the package is invalid.
hotspotDisconnectedDuringTransfer, invalidHotspotConfigThe device hotspot cannot be used reliably.
stageTwoTimeout, interruptedByShutdownOrLowBatteryFlashing stalls near completion or the device interrupts the update.
cameraOtaTaskAlreadyRunningAnother Camera OTA task is active.
4003...4009The task fails during device connection, timeout, hotspot setup, OTA-mode entry, HTTP serving, or URL delivery.
5001...5010The device rejects OTA-mode entry or firmware-URL delivery because of command, storage, permission, channel, or state conditions.

Show the failing workflow stage rather than a generic update error. Once flashing begins, do not automatically retry, disconnect, shut down, or start another hotspot workflow. The SDK does not currently define authoritative retry boundaries; confirm device recovery state and camera firmware version before offering another package.

Best Practices

  1. Validate that the local file exists before calling the API; package authenticity and camera-model compatibility remain the host product's responsibility.
  2. Prevent concurrent Media File Import, Camera OTA, or other hotspot workflows.
  3. Keep the app active and the local HTTP server reachable until final completion.
  4. Dispatch UI updates to the main queue because callbacks may arrive on another queue.
  5. Treat startCompletionHandler as the result of starting the OTA operation, not as final upgrade success.
  6. Use completionHandler as the final result and verify the camera firmware state after reconnecting.

Notes

  • Camera OTA uses a local firmware path; the SDK does not query a remote update service or download the package.
  • phaseProgressHandler reports only transfer and flashing progress. Other workflow stages use their dedicated callbacks.
  • A progress value of 100 for transfer is not the final Camera OTA result; flashing and final completion still follow.
  • Safe automatic retry behavior is not currently defined by the public SDK contract.