我正在開發一個使用 BLE 連接到 ESP32 的 iPhone 的專案。我正在嘗試將 528 位元組長的 blob 寫入特征。由于 blob 比每次寫入允許的最大 512 長,我正在嘗試執行 Write Long。
我嘗試了幾件事
1 - 如果我只是嘗試寫入 blob,我會看到第一個塊使用 Prepare Write set 完成,但沒有后續寫入。
為什么它在第一個塊之后停止?
2 - 如果我嘗試根據從 maximumWriteValueLengthForType 回傳的大小手動洗掉它,我會看到所有資料都已正確發送,但未設定 Prepare Write,因此無法正確處理它們。
如何指定 Prepare Write / Execute Write 請求?
這是一個涵蓋實作#2的代碼片段
NSData *blob = [request value];
NSUInteger localLength = 0;
NSUInteger totalLength = [blob length];
NSUInteger chunkSize = [peripheral maximumWriteValueLengthForType:type];
uint8_t localBytes[chunkSize];
NSData *localData;
do
{
if(totalLength > chunkSize) {
NSLog(@"BIGGER THAN CHUNK!!!!!!!!!!!!!!!!!!!!!");
NSLog(@"%tu", chunkSize);
for ( int i = 0; i < chunkSize; i ) {
localBytes[i] = ((uint8_t *)blob.bytes)[localLength i];
}
localData = [NSMutableData dataWithBytes:localBytes length:chunkSize];
totalLength -= chunkSize;
localLength = chunkSize;
}
else {
NSLog(@"Smaller than chunk");
uint8_t lastBytes[totalLength];
for (int i = 0 ; i < totalLength; i ) {
lastBytes[i] = ((uint8_t *)blob.bytes)[localLength i];
}
localData = [NSMutableData dataWithBytes:lastBytes length:totalLength];
totalLength = 0;
}
// Write to characteristic
[peripheral writeValue: localData forCharacteristic:characteristic type:type];
} while( totalLength > 0);
uj5u.com熱心網友回復:
長寫入受到特征值最大 512 位元組的相同限制的影響。僅當 MTU 太短而無法在一個資料包中寫入完整值時,長寫入才有用。也許你正試圖寫出這個允許的范圍或其他東西。
與 BLE 5 設備通信的較新 iOS 版本使用足夠大的 MTU 以在一個資料包中容納 512 的特征值(如果遠程設備也支持如此大的 MTU)。
如果要寫入大于 512 位元組的值,則需要將其拆分為多個寫入,以便第二次寫入“覆寫”發送的第一個值,而不是附加到它。您也可以改用 L2CAP CoC,它消除了這個任意 512 位元組的限制。
uj5u.com熱心網友回復:
您有正確的通用方法,但您不能只按順序發送塊。發送藍牙資料的緩沖區有限,您的回圈將比藍牙硬體發送資料更快地將資料寫入該緩沖區。
您需要采取的確切方法取決于您的特性是支持寫入回應還是寫入不回應。
如果您的特征使用帶回應的寫入,您應該發送一個塊,然后等到您呼叫didWriteValueFor
委托方法。然后,您可以撰寫下一個塊。這種方法的優點是基本上保證了資料的交付。缺點是比較慢。
如果您的特征使用 write without response,那么您會write
重復呼叫,直到您收到didWriteValueFor
錯誤的呼叫。在這一點上,你必須等到你接到電話peripheralIsReady
。此時您可以重新開始寫入,從上次失敗的寫入開始。
使用這種方法可能會丟失資料,但速度更快。
如果您必須移動大量資料,L2Cap 流可能會更好,但您需要處理資料幀。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/508526.html