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.
Camera OTA delivery path
A local package moves from host-side validation through SDK orchestration to transfer, flashing, and the authoritative final 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
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.API Reference
Framework
AIBuds.xcframework
Import
- Swift
- Objective-C
import AIBuds
import AIBudsFoundation#import <AIBuds/AIBuds-Swift.h>
#import <AIBuds/AIBuds.h>Protocol
The DeviceCameraOtaAPI protocol inherits from DeviceAPI and currently exposes one instance method for the complete Camera OTA workflow.
Instance Method
- Swift
- Objective-C
/// 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?
)/// Start camera OTA upgrade from a local firmware path.
///
/// - Parameters:
/// - filePath: The readable local path of the camera firmware file.
/// - configureHotspotStartingHandler: Called when hotspot configuration starts.
/// - hotspotConfigureCompletionHandler: Returns configuration success and error.
/// - enterCameraOtaModeStartingHandler: Called when entry into camera OTA mode starts.
/// - enterCameraOtaModeCompletedHandler: Returns OTA-mode entry success and error.
/// - waitingForHotspotOpenHandler: Called while waiting for the device hotspot to open.
/// - connectDeviceHotspotStartingHandler: Returns the device hotspot SSID.
/// - deviceHotspotConnectCompletionHandler: Returns hotspot connection success and error.
/// - httpServerStartingHandler: Called when the local HTTP server is starting.
/// - httpServerStartCompletionHandler: Returns HTTP server start success and error.
/// - sendingFirmwareUrlHandler: Returns the local firmware URL before it is sent.
/// - firmwareUrlSendCompletionHandler: Returns URL delivery success and error.
/// - startCompletionHandler: Returns Camera OTA start success and error.
/// - fileTransferStartedHandler: Called when firmware transfer starts.
/// - fileTransferCompletedHandler: Called when firmware transfer completes.
/// - waitingForFlashingHandler: Called while the device prepares to flash.
/// - flashingStartedHandler: Called when firmware flashing starts.
/// - flashingCompletedHandler: Called when firmware flashing completes.
/// - phaseProgressHandler: Returns `Transferring` or `Flashing` and progress from `0` to `100`.
/// - completionHandler: Returns final upgrade success and error.
- (void)startCameraOtaWithFilePath:(NSString *_Nonnull)filePath
configureHotspotStartingHandler:(AIBudsCameraOtaConfigureHotspotStartingHandler _Nullable)
configureHotspotStartingHandler
hotspotConfigureCompletionHandler:
(AIBudsCameraOtaHotspotConfigureCompletionHandler _Nullable)
hotspotConfigureCompletionHandler
enterCameraOtaModeStartingHandler:
(AIBudsEnterCameraOtaModeStartingHandler _Nullable)enterCameraOtaModeStartingHandler
enterCameraOtaModeCompletedHandler:
(AIBudsEnterCameraOtaModeCompletionHandler _Nullable)enterCameraOtaModeCompletedHandler
waitingForHotspotOpenHandler:
(AIBudsCameraOtaStartingToWaitForHotspotOpenHandler _Nullable)
waitingForHotspotOpenHandler
connectDeviceHotspotStartingHandler:
(AIBudsCameraOtaConnectDeviceHotspotStartingHandler _Nullable)
connectDeviceHotspotStartingHandler
deviceHotspotConnectCompletionHandler:
(AIBudsCameraOtaDeviceHotspotConnectCompletionHandler _Nullable)
deviceHotspotConnectCompletionHandler
httpServerStartingHandler:
(AIBudsCameraOtaHttpServerStartingHandler _Nullable)httpServerStartingHandler
httpServerStartCompletionHandler:
(AIBudsCameraOtaHttpServerStartCompletionHandler _Nullable)
httpServerStartCompletionHandler
sendingFirmwareUrlHandler:
(AIBudsCameraOtaSendingFirmwareUrlHandler _Nullable)sendingFirmwareUrlHandler
firmwareUrlSendCompletionHandler:
(AIBudsCameraOtaFirmwareUrlSendCompletionHandler _Nullable)
firmwareUrlSendCompletionHandler
startCompletionHandler:
(AIBudsCameraOtaStartCompletionHandler _Nullable)startCompletionHandler
fileTransferStartedHandler:
(AIBudsCameraOtaFileTransferStartedHandler _Nullable)fileTransferStartedHandler
fileTransferCompletedHandler:
(AIBudsCameraOtaFileTransferCompletedHandler _Nullable)fileTransferCompletedHandler
waitingForFlashingHandler:
(AIBudsCameraOtaWaitingForFlashingHandler _Nullable)waitingForFlashingHandler
flashingStartedHandler:
(AIBudsCameraOtaFlashingStartedHandler _Nullable)flashingStartedHandler
flashingCompletedHandler:
(AIBudsCameraOtaFlashingCompletedHandler _Nullable)flashingCompletedHandler
phaseProgressHandler:
(AIBudsCameraOtaPhaseProgressHandler _Nullable)phaseProgressHandler
completionHandler:
(AIBudsCameraOtaCompletionHandler _Nullable)completionHandler;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.
| Stage | Related handlers |
|---|---|
| Configure hotspot | configureHotspotStartingHandler, hotspotConfigureCompletionHandler |
| Enter Camera OTA mode | enterCameraOtaModeStartingHandler, enterCameraOtaModeCompletedHandler |
| Connect device hotspot | waitingForHotspotOpenHandler, connectDeviceHotspotStartingHandler, deviceHotspotConnectCompletionHandler |
| Start local HTTP server | httpServerStartingHandler, httpServerStartCompletionHandler |
| Send firmware URL | sendingFirmwareUrlHandler, firmwareUrlSendCompletionHandler |
| Start update | startCompletionHandler |
| Transfer firmware | fileTransferStartedHandler, fileTransferCompletedHandler |
| Prepare and flash | waitingForFlashingHandler, flashingStartedHandler, flashingCompletedHandler |
| Finish | completionHandler |
Progress Phases
CameraOtaProgressPhase contains exactly two public values. The progress argument is an integer from 0 through 100 for the reported phase.
| Swift | Objective-C | Raw value | Meaning |
|---|---|---|---|
.transferring | AIBudsCameraOtaProgressPhaseTransferring | 1 | Firmware file transfer progress. |
.flashing | AIBudsCameraOtaProgressPhaseFlashing | 2 | Camera 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
- Objective-C
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")")
}
}
)id<AIBudsDeviceCameraOtaAPI> cameraOtaDevice = (id<AIBudsDeviceCameraOtaAPI>)self.device;
if (![cameraOtaDevice conformsToProtocol:@protocol(AIBudsDeviceCameraOtaAPI)]) {
NSLog(@"Camera OTA is not supported");
return;
}
[cameraOtaDevice startCameraOtaWithFilePath:filePath
configureHotspotStartingHandler:^{
NSLog(@"Configuring device hotspot");
}
hotspotConfigureCompletionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Hotspot configured" : error.localizedDescription);
}
enterCameraOtaModeStartingHandler:^{
NSLog(@"Entering Camera OTA mode");
}
enterCameraOtaModeCompletedHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Camera OTA mode ready" : error.localizedDescription);
}
waitingForHotspotOpenHandler:^{
NSLog(@"Waiting for device hotspot");
}
connectDeviceHotspotStartingHandler:^(NSString *_Nonnull ssid) {
NSLog(@"Connecting to %@", ssid);
}
deviceHotspotConnectCompletionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Device hotspot connected" : error.localizedDescription);
}
httpServerStartingHandler:^{
NSLog(@"Starting local HTTP server");
}
httpServerStartCompletionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"HTTP server ready" : error.localizedDescription);
}
sendingFirmwareUrlHandler:^(NSString *_Nonnull firmwareUrl) {
NSLog(@"Sending firmware URL: %@", firmwareUrl);
}
firmwareUrlSendCompletionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Firmware URL sent" : error.localizedDescription);
}
startCompletionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Camera OTA started" : error.localizedDescription);
}
fileTransferStartedHandler:^{
NSLog(@"Firmware transfer started");
}
fileTransferCompletedHandler:^{
NSLog(@"Firmware transfer completed");
}
waitingForFlashingHandler:^{
NSLog(@"Waiting for flashing");
}
flashingStartedHandler:^{
NSLog(@"Firmware flashing started");
}
flashingCompletedHandler:^{
NSLog(@"Firmware flashing completed");
}
phaseProgressHandler:^(AIBudsCameraOtaProgressPhase phase, NSInteger progress) {
if (phase == AIBudsCameraOtaProgressPhaseTransferring) {
NSLog(@"Transfer: %ld%%", (long)progress);
} else if (phase == AIBudsCameraOtaProgressPhaseFlashing) {
NSLog(@"Flashing: %ld%%", (long)progress);
}
}
completionHandler:^(BOOL success, NSError *_Nullable error) {
NSLog(@"%@", success ? @"Camera OTA completed successfully" : error.localizedDescription);
}];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.
| Codes | Typical condition |
|---|---|
unknown, networkRequestFailed, networkTimeout | The SDK cannot classify the error more narrowly or network activity fails. |
cameraOtaFileNotFound, invalidCameraOtaFile, cameraOtaTaskCreateFailedDueToFileNotFound | The selected local firmware path is missing or the package is invalid. |
hotspotDisconnectedDuringTransfer, invalidHotspotConfig | The device hotspot cannot be used reliably. |
stageTwoTimeout, interruptedByShutdownOrLowBattery | Flashing stalls near completion or the device interrupts the update. |
cameraOtaTaskAlreadyRunning | Another Camera OTA task is active. |
4003...4009 | The task fails during device connection, timeout, hotspot setup, OTA-mode entry, HTTP serving, or URL delivery. |
5001...5010 | The 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
- Validate that the local file exists before calling the API; package authenticity and camera-model compatibility remain the host product's responsibility.
- Prevent concurrent Media File Import, Camera OTA, or other hotspot workflows.
- Keep the app active and the local HTTP server reachable until final completion.
- Dispatch UI updates to the main queue because callbacks may arrive on another queue.
- Treat
startCompletionHandleras the result of starting the OTA operation, not as final upgrade success. - Use
completionHandleras 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.
phaseProgressHandlerreports only transfer and flashing progress. Other workflow stages use their dedicated callbacks.- A progress value of
100for 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.