@kezhen
2015-08-19T03:33:05.000000Z
字数 4210
阅读 1879
蓝牙升级流程
SPOTA_MEM_DEV_UUID
写值来设置内存类型(memoryType
)
// Step 1: Set memory type
step = 0;
expectedValue = 0x10;
nextStep = 2;
int _memDevData = (self.memoryType << 24) | (self.memoryBank & 0xFF);
[self debug:[NSString stringWithFormat:@"Sending data: %#10x", _memDevData]];
NSData *memDevData = [NSData dataWithBytes:&_memDevData length:sizeof(int)];
// 往特征写值成功后将回调两个方法
[manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID]
characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID]
p:manager.device data:memDevData];
SPOTA_GPIO_MAP_UUID
写值设置存储器参数
int _memInfoData
if (self.memoryType == MEM_TYPE_SUOTA_SPI) {
_memInfoData = (self.spiMISOAddress << 24) | (self.spiMOSIAddress << 16) | (self.spiCSAddress << 8) | self.spiSCKAddress;
} else if (self.memoryType == MEM_TYPE_SUOTA_I2C) {
_memInfoData = (self.i2cAddress << 16) | (self.i2cSCLAddress << 8) | self.i2cSDAAddress;
}
SPOTA_GPIO_MAP_UUID
写值
[manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_GPIO_MAP_UUID] p:manager.device data:memInfoData];
[self debug:[NSString stringWithFormat:@"Loading data from %@", [storage.file_url absoluteString]]];
fileData = [[NSData dataWithContentsOfURL:storage.file_url] mutableCopy];
[self appendChecksum];
chunkSize = 20;
blockStartByte = 0;
SPOTA_PATCH_LEN_UUID
写值设置镜像长度数据
NSData *patchLengthData = [NSData dataWithBytes:&blockSize length:sizeof(UInt16)];
[manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_PATCH_LEN_UUID] p:manager.device data:patchLengthData];
blockSize是发送镜像的数据块大小,默认是240字节。
characteristic.value
调用getByte:length
方法得到结果信息,失败弹窗提示错误,成功则log日志并重复执行第五步骤。
- (void) didUpdateValueForCharacteristic: (NSNotification*)notification {
CBCharacteristic *characteristic = (CBCharacteristic*) notification.object;
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:SPOTA_SERV_STATUS_UUID]]) {
char value;
[characteristic.value getBytes:&value length:sizeof(char)];
NSString *message = [self getErrorMessage:value];
[self debug:message];
// 通过第五步骤跳转到此方法,expectedValue = 0x02
if (expectedValue != 0) {
// Check if value equals the expected value
if (value == expectedValue) { // 得到期望值
// If so, continue with the next step
step = nextStep; // 通过第五步骤跳转到此方法,nextStep = 5
expectedValue = 0; // Reset
[self doStep];
} else { // 出现错误
// Else display an error message
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
expectedValue = 0; // Reset
[autoscrollTimer invalidate]; // 关闭刷新textView的大小
}
}
}
}
N
个blockSize
大小的数据,剩余镜像数据为bytesRemaining
。 chunkStartByte
(局部变量,初始化为0,每次累加20)大于或等于blockSize
时,则更新镜像起始块大小(blockStartByte,全局变量,初始化为0)。bytesRemaining < blockSize
时,让blockSize = bytesRemaining
并跳转到第四步(step = 4),重新设置镜像块大小。bytesRemaining = 0
时,跳转到第六步发送结束命令并跳转到第七步提示用户是否重启外围设备。
// On to the chunk
chunkStartByte += chunkSize;
// Check if we are passing the current block
if (chunkStartByte >= blockSize) {
// Prepare for next block
blockStartByte += blockSize;
int bytesRemaining = dataLength - blockStartByte;
if (bytesRemaining == 0) {
nextStep = 6;
} else if (bytesRemaining < blockSize) {
blockSize = bytesRemaining;
nextStep = 4; // Back to step 4, setting the patch length
}
}
// Send SUOTA END command
step = 0;
expectedValue = 0x02;
nextStep = 7;
int suotaEnd = 0xFE000000;
[self debug:[NSString stringWithFormat:@"Sending data: %#10x", suotaEnd]];
NSData *suotaEndData = [NSData dataWithBytes:&suotaEnd length:sizeof(int)];
[manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID] p:manager.device data:suotaEndData];
if (buttonIndex != alertView.cancelButtonIndex) {
// Send reboot signal to device
step = 8; // 返回到扫描设备的界面
int suotaEnd = 0xFD000000;
[self debug:[NSString stringWithFormat:@"Sending data: %#10x", suotaEnd]];
NSData *suotaEndData = [NSData dataWithBytes:&suotaEnd length:sizeof(int)];
[manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID] p:manager.device data:suotaEndData];
}