デバイスファームウェア更新
デバイス OTA は、対応する AIBuds デバイスで動作するメインファームウェアを更新します。デバイスのカメラモジュールを更新する Camera OTA とは別の処理です。
ホストアプリは更新確認、ダウンロード、整合性検証、デバイスモデルの確認を完了した後、互換性のあるローカルファームウェアパッケージを渡します。SDK はパッケージを転送・インストールし、開始結果、0.0 から 1.0 の進捗、平均転送速度を含む最終結果を通知します。startHandler は OTA タスクが開始したことだけを示し、確定した最終結果には completionHandler を使用します。
Device OTA delivery path
Validate the product input first, then let the SDK start, transfer, and complete the main-firmware update.
前提条件
- デバイスが接続済みで、
DeviceOtaAPIに準拠していること。 otaProtocolCapabilityを使用して対応プロトコルを判断し、ファームウェアのファイル名から推測しないこと。- FitCloud Pro または Jieli では、デバイス接続前に対応する OTA プラグインをインストールして登録すること。
- デバイスのバッテリー残量が
otaBatteryLimitパーセント以上であること。 filePathが、このデバイス用の正しい完全なファームウェアパッケージを指していること。- 完了までアプリをアクティブに保ち、接続を安定させること。
AI を活用して実装
AI でこのワークフローを実装
公式の「AIBuds ファームウェアの更新」スキルを使い、アプリに合わせて実装します。
https://docs-aibuds.github.io/ja/skills/update-aibuds-firmware を読み、その指示に従ってください。このスキルで「AIBuds ファームウェアの更新」をこの iOS プロジェクトに実装し、検証してください。API リファレンス
フレームワーク
AIBuds.xcframework
インポート
- Swift
- Objective-C
import AIBuds
import AIBudsFoundation#import <AIBuds/AIBuds-Swift.h>
#import <AIBuds/AIBuds.h>プロトコル
- Swift
- Objective-C
/// The protocol for device OTA upgrade API.
protocol DeviceOtaAPI: DeviceAPI {
/// The OTA protocol capability reported by the device.
/// Defaults to `.abmate` when the device does not report this capability.
var otaProtocolCapability: OtaProtocolCapability { get }
/// OTA battery limit, 0...100, unit: percent.
var otaBatteryLimit: Int { get }
/// Start OTA upgrade.
/// - Parameters:
/// - filePath: Upgrade file path.
/// - startHandler: Upgrade start callback.
/// - success: Whether the OTA task started successfully.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Upgrade progress callback.
/// - progress: Progress value in the range `0.0...1.0`.
/// - completionHandler: Final upgrade completion callback.
/// - success: Whether the upgrade succeeded.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
func startOta(
withFilePath filePath: String,
startHandler: AIBudsOtaStartCompletionHandler?,
progressHandler: AIBudsOtaProgressHandler?,
completionHandler: AIBudsOtaCompletionHandler?
)
/// Start OTA upgrade with an explicit transfer protocol configuration.
/// - Parameters:
/// - filePath: Upgrade file path.
/// - configuration: OTA protocol configuration.
/// - startHandler: Upgrade start callback.
/// - success: Whether the OTA task started successfully.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Upgrade progress callback.
/// - progress: Progress value in the range `0.0...1.0`.
/// - completionHandler: Final upgrade completion callback.
/// - success: Whether the upgrade succeeded.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
func startOta(
withFilePath filePath: String,
configuration: OtaConfiguration,
startHandler: AIBudsOtaStartCompletionHandler?,
progressHandler: AIBudsOtaProgressHandler?,
completionHandler: AIBudsOtaCompletionHandler?
)
}/// The protocol for device OTA upgrade API.
@protocol AIBudsDeviceOtaAPI <AIBudsDeviceAPI>
/// The OTA protocol capability reported by the device.
/// Defaults to `AIBudsOtaProtocolCapabilityAbmate` when the device does not report it.
@property(nonatomic, readonly) AIBudsOtaProtocolCapability otaProtocolCapability;
/// OTA battery limit, 0...100, unit: percent.
@property(nonatomic, readonly) NSInteger otaBatteryLimit;
/// Start OTA upgrade from a local firmware path.
///
/// - Parameters:
/// - filePath: The readable local firmware file path.
/// - startHandler: Called when the OTA start attempt completes.
/// - success: `YES` if the OTA task started; otherwise `NO`.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Called when OTA progress changes.
/// - progress: Progress in the range `0.0...1.0`.
/// - completionHandler: Called when the OTA operation finishes.
/// - success: `YES` if the upgrade succeeded; otherwise `NO`.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
- (void)startOtaWithFilePath:(NSString *_Nonnull)filePath
startHandler:(AIBudsOtaStartCompletionHandler _Nullable)startHandler
progressHandler:(AIBudsOtaProgressHandler _Nullable)progressHandler
completionHandler:(AIBudsOtaCompletionHandler _Nullable)completionHandler;
/// Start OTA upgrade with an explicit transfer protocol configuration.
///
/// - Parameters:
/// - filePath: The readable local firmware file path.
/// - configuration: The OTA protocol configuration required by the device.
/// - startHandler: Called when the OTA start attempt completes.
/// - success: `YES` if the OTA task started; otherwise `NO`.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Called when OTA progress changes.
/// - progress: Progress in the range `0.0...1.0`.
/// - completionHandler: Called when the OTA operation finishes.
/// - success: `YES` if the upgrade succeeded; otherwise `NO`.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
- (void)startOtaWithFilePath:(NSString *_Nonnull)filePath
configuration:(AIBudsOtaConfiguration *_Nonnull)configuration
startHandler:(AIBudsOtaStartCompletionHandler _Nullable)startHandler
progressHandler:(AIBudsOtaProgressHandler _Nullable)progressHandler
completionHandler:(AIBudsOtaCompletionHandler _Nullable)completionHandler;
@endAPI リファレンスの otaProtocolCapability、otaBatteryLimit、および startOta のオーバーロードを参照してください。
デバイス機能
デバイスの準備完了後に otaProtocolCapability を読み取り、選択可能なプロトコルを制限します。
| Swift | Objective-C | Raw value | 対応プロトコル |
|---|---|---|---|
.none | AIBudsOtaProtocolCapabilityNone | -1 | OTA 対応が報告されていません。 |
.abmate | AIBudsOtaProtocolCapabilityAbmate | 0 | ABMate。機能が報告されない場合のフォールバックでもあります。 |
.fitcloudPro | AIBudsOtaProtocolCapabilityFitcloudPro | 1 | FitCloud Pro。FitCloud Pro プラグインが必要です。 |
.abmateAndFitcloudPro | AIBudsOtaProtocolCapabilityAbmateAndFitcloudPro | 2 | ABMate と FitCloud Pro。登録済みの選択肢だけを表示します。 |
.jieli | AIBudsOtaProtocolCapabilityJieli | 3 | Jieli シングルバンク OTA。Jieli プラグインが必要です。 |
OTA 設定
OtaConfiguration は、設定付きオーバーロードで使用する BLE OTA プロトコルを選択します。otaProtocol プロパティの既定値は .abmate です。
| Swift | Objective-C | raw value | 意味 |
|---|---|---|---|
.abmate | AIBudsOtaProtocolKindAbmate | 0 | ABMate OTA プロトコル。 |
.fitcloudPro | AIBudsOtaProtocolKindFitcloudPro | 1 | FitCloud Pro OTA プロトコル。 |
.jieli | AIBudsOtaProtocolKindJieli | 2 | Jieli シングルバンク OTA プロトコル。 |
ファームウェアファイルから推測してプロトコルを選ばないでください。接続デバイスと製品統合で必要なプロトコルを使用します。
任意の OTA プラグイン
FitCloud Pro と Jieli は個別の CocoaPods subspec です。必要な BLE characteristic を SDK が検出して subscribe できるよう、デバイス接続前にプラグインを登録してください。AIBudsSDK/AllInOne は両方を自動的にインストールして登録します。
pod 'AIBudsSDK/FitCloudProOTA'
pod 'AIBudsSDK/JieliOTA'import AIBuds
import AIBudsFitCloudProOTA
import AIBudsJieliOTA
AIBudsSDK.registerOtaPlugin(FitCloudProOtaSDK.otaPlugin)
AIBudsSDK.registerOtaPlugin(JieliOtaSDK.otaPlugin)モジュール統合では、製品が提供する実装だけを登録します。同じ OtaProtocolKind を後から登録すると、以前のプラグインが置き換えられます。利用可能かどうかは AIBudsSDK.otaPlugin(for:) で確認し、登録解除には AIBudsSDK.removeOtaPlugin(for:) を使用します。
戻り値
どちらのオーバーロードも値を直接返しません。startHandler は OTA タスクの開始結果、progressHandler は正規化済み進捗、completionHandler は確定した最終結果と平均転送速度を通知します。
使用例
- Swift
- Objective-C
guard let device = device as? DeviceOtaAPI else { return }
guard deviceBatteryPercent >= device.otaBatteryLimit else {
print("Charge the device before updating")
return
}
device.startOta(
withFilePath: firmwareURL.path,
startHandler: { success, error in
if !success { print(error?.localizedDescription ?? "OTA failed to start") }
},
progressHandler: { progress in
print("OTA: \(Int(progress * 100))%")
},
completionHandler: { success, averageSpeed, error in
print(
success
? "OTA completed at \(averageSpeed) kB/s"
: (error?.localizedDescription ?? "OTA failed"))
})id<AIBudsDeviceOtaAPI> device = (id<AIBudsDeviceOtaAPI>)self.device;
if (![device conformsToProtocol:@protocol(AIBudsDeviceOtaAPI)])
return;
[device startOtaWithFilePath:firmwareURL.path
startHandler:^(BOOL success, NSError *_Nullable error) {
if (!success)
NSLog(@"OTA failed to start: %@", error.localizedDescription);
}
progressHandler:^(CGFloat progress) {
NSLog(@"OTA: %.0f%%", progress * 100);
}
completionHandler:^(BOOL success, CGFloat averageSpeed, NSError *_Nullable error) {
if (success) {
NSLog(@"OTA completed at %.2f kB/s", averageSpeed);
} else {
NSLog(@"OTA failed: %@", error.localizedDescription);
}
}];OTA プロトコルを明示指定
接続デバイスが必要とする OTA プロトコルを製品側で把握している場合にのみ、設定付きオーバーロードを使用します。
- Swift
- Objective-C
let configuration = OtaConfiguration()
configuration.otaProtocol = .fitcloudPro
device.startOta(
withFilePath: firmwareURL.path,
configuration: configuration,
startHandler: { success, error in
if !success {
print(error?.localizedDescription ?? "OTA failed to start")
}
},
progressHandler: { progress in
print("OTA: \(Int(progress * 100))%")
},
completionHandler: { success, averageSpeed, error in
print(
success
? "OTA completed at \(averageSpeed) kB/s"
: (error?.localizedDescription ?? "OTA failed"))
}
)AIBudsOtaConfiguration *configuration = [[AIBudsOtaConfiguration alloc] init];
configuration.otaProtocol = AIBudsOtaProtocolKindFitcloudPro;
[device startOtaWithFilePath:firmwareURL.path
configuration:configuration
startHandler:^(BOOL success, NSError *_Nullable error) {
if (!success)
NSLog(@"OTA failed to start: %@", error.localizedDescription);
}
progressHandler:^(CGFloat progress) {
NSLog(@"OTA: %.0f%%", progress * 100);
}
completionHandler:^(BOOL success, CGFloat averageSpeed, NSError *_Nullable error) {
if (success) {
NSLog(@"OTA completed at %.2f kB/s", averageSpeed);
} else {
NSLog(@"OTA failed: %@", error.localizedDescription);
}
}];エラー処理
OTA エラーには AIBudsSDK.OtaErrorDomain と SdkOtaErrorCode を使用します。
| コード | 主な状況 |
|---|---|
unknown | SDK がエラーをこれ以上分類できません。 |
otaTaskAlreadyRunning | 別の OTA タスクがすでに実行中です。 |
otaTaskCreateFailedDueToFileNotFound | ローカルファームウェアのパスが存在しません。 |
otaTaskStartFailedDueToFileReadError, otaTaskStartFailedDueToFileHandleCreateError | パッケージを開く、または読み取ることができません。 |
otaTaskStartFailedDueToInvalidFileHashData | ファームウェアのハッシュデータが無効です。 |
otaTaskStartFailedDueToGetOtaInfoError | 必要な OTA メタデータを取得できません。 |
otaTaskStartFailedDueToInvalidOffsetAddress, otaTaskStartFailedDueToInvalidBlockSize | 転送メタデータが無効です。 |
otaTaskStartFailedDueToNotAllowUpdate | デバイスの現在状態では更新が許可されていません。 |
otaTaskSendDataFailedDueToFileHandleIsNil, otaTaskSendDataFailedDueToSeekFileHandleFailed, otaTaskSendDataFailedDueToReadFileDataFailed, otaTaskSendDataFailedDueToOtaInfoIsNil | SDK がファームウェアデータの読み取りまたは送信を継続できません。 |
otaTaskFailedDueToDeviceReportKeyMismatch, otaTaskFailedDueToDeviceReportCrcError, otaTaskFailedDueToDeviceReportSeqError, otaTaskFailedDueToDeviceReportDataLengthError | デバイスが転送データを拒否したか、整合性またはシーケンスの問題を報告しました。 |
otaTaskFailedDueToDeviceDisconnect, otaTaskFailedDueToTimeout | デバイスが切断されたか、処理がタイムアウトしました。 |
startHandler の失敗と、転送開始後の失敗を区別します。未検証のパッケージで自動再試行せず、まずデバイスモデル、ファームウェアバージョン、パッケージ整合性、バッテリー、プロトコル選択、接続を再確認してください。
ベストプラクティス
- SDK を呼び出す前に、更新の検出、ダウンロード、署名または整合性検証、デバイスモデル互換性の確認を完了します。
- 更新 UI の表示時だけでなく、開始直前にも
otaBatteryLimitを確認します。 - OTA、Camera OTA、メディアファイル取り込み、その他の長時間デバイス処理を同時実行しないでください。
- コールバックは別のキューで届く場合があるため、UI 更新をメインキューへ切り替えます。
startHandlerはタスク開始確認としてのみ扱い、completionHandlerが成功するまで更新成功を報告しないでください。- 最終完了までアプリをアクティブに保ち、デバイス接続を安定させます。再接続後に通知されたファームウェアバージョンを確認します。
注意事項
- 進捗は
0.0...1.0に正規化されています。SDK の結果は変更せず、UI 表示側で安全に範囲を制限してください。 avgSpeedは最終完了ハンドラーでのみ kB/s 単位で通知されます。OtaConfiguration.otaProtocolの既定値は.abmateです。.fitcloudProまたは.jieliは、otaProtocolCapabilityとインストール済みプラグインが対応している場合にのみ選択してください。- SDK は OTA のキャンセルメソッドを公開していません。Demo の Cancel ボタンはローカル UI 状態をリセットするだけであり、SDK 処理をキャンセルするものとして説明しないでください。