【IOS】BLE-蓝牙空中升级(OAD)

蓝牙为CC2541 ios升级蓝牙固件;

1.头文件

#import

升级要用到的ID

#define BT_OAD_SERVICE @"F000FFC0-0451-4000-B000-000000000000"

#define BT_OAD_IMAGE_NOTIFY @"F000FFC1-0451-4000-B000-000000000000"

#define BT_OAD_IMAGE_BLOCK_REQUEST @"F000FFC2-0451-4000-B000-000000000000"

2.获取蓝牙列表,选择需要升级的蓝牙


【IOS】BLE-蓝牙空中升级(OAD)_第1张图片

3.获取所有的特征值,找到我们需要的通道,设置通道的模式为监测通道变化

[peripheral setNotifyValue:YES forCharacteristic:characteristic];

传过去所需的参数

[controller setCharacteristic_oad_1:connectDic[BT_OAD_IMAGE_NOTIFY]];通道1

[controller setCharacteristic_oad_2:connectDic[BT_OAD_IMAGE_BLOCK_REQUEST]]通道2

[controller setDetailItem:self.detailItem];//蓝牙CBPeripheral



【IOS】BLE-蓝牙空中升级(OAD)_第2张图片


4.指定蓝牙的代理和代理方法

self.detailItem.delegate = self;

//[characteristic.value bytes]

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error

5.选择要升级的文件(这里是本地)

NSString *filePathA = [[NSBundle mainBundle] pathForResource:@"ImageA"    ofType:@"bin"];

NSString *filePathB = [[NSBundle mainBundle] pathForResource:@"ImageB"   ofType:@"bin"];

oad_A_Data = [NSData dataWithContentsOfFile:filePathA];

oad_B_Data = [NSData dataWithContentsOfFile:filePathB];

if (row == 1) {

oadData = oad_A_Data;

[self sendBlueToothUP];

}else if (row == 2) {

oadData = oad_B_Data;

[self sendBlueToothUP];

}

【IOS】BLE-蓝牙空中升级(OAD)_第3张图片
【IOS】BLE-蓝牙空中升级(OAD)_第4张图片

6.开始进行蓝牙升级:

(1)发送一个字节数据来获取蓝牙设备的当前设备信息

- (void)sendBlueToothUP{

if (!self.characteristic_oad_1||!self.characteristic_oad_2) {

[[AlertShowView sharedInstance] showMessage:@"通道错误"];return;}

Byte byte[] = {};

NSData *data = [NSData dataWithBytes:byte length:sizeof(byte)];

[self.detailItem writeValue:data forCharacteristic:self.characteristic_oad_1 type:CBCharacteristicWriteWithResponse];

}

(2)在代理处接收返回数据

- (void)readValueWithCharacteristics:(CBCharacteristic *)characteristic andPer:(CBPeripheral *)peripheral{

NSLog(@"\\nreadValue-%@",characteristic.value);

if ([characteristic.UUID.UUIDString isEqualToString:BT_OAD_IMAGE_NOTIFY]) {

if (characteristic.value) {

[self compareVerWithCharacteristics:characteristic];}

}}

(3)处理接收的数据,如果版本不相同,就把本地文件的固件信息通过通道1发送过去;

固件信息包含的信息有:固件版本、固件长度、固件类型

- (void)compareVerWithCharacteristics:(CBCharacteristic *)characteristic{

Byte *Cvalue = (Byte *)[characteristic.value bytes];

Byte *Dvalue = (Byte *)[oadData bytes];

if ((Cvalue[0] & 0x01) != ( Dvalue[4] & 0x01)) {//对比版本信息

NSLog(@"可以升级");

x = 0;

Byte byte[] = {Dvalue[4],Dvalue[5],Dvalue[6],Dvalue[7],Dvalue[8],Dvalue[9],Dvalue[10],Dvalue[11]};//本地数据的固件信息

NSData *sendData = [NSData dataWithBytes:byte length:sizeof(byte)];

NSLog(@"%@",sendData);

[self.detailItem writeValue:sendData forCharacteristic:self.characteristic_oad_1 type:CBCharacteristicWriteWithResponse];

}else{

[[AlertShowView sharedInstance] showInView:self.view andMessage:@"版本相同"];

}}

(4)在代理处接收返回数据(如果成功会通过通道2返回数据)

- (void)readValueWithCharacteristics:(CBCharacteristic *)characteristic andPer:(CBPeripheral *)peripheral{

NSLog(@"\\nreadValue-%@",characteristic.value);

if ([characteristic.UUID.UUIDString isEqualToString:BT_OAD_IMAGE_NOTIFY]) {

if (characteristic.value) {

[self compareVerWithCharacteristics:characteristic];}

}else if ([characteristic.UUID.UUIDString isEqualToString:BT_OAD_IMAGE_BLOCK_REQUEST]){

if (characteristic.value) {

[self.detailItem setNotifyValue:NO forCharacteristic:characteristic];//第二中方法才需要

[self startSendData];//第二种方法

//[self sendDataWithCharacteristics:characteristic];//第一种方法

}}}

(5)处理数据,开始发送本地文件;收到的数据是需要发送数据的序号(0000-FFFF,高位在后;0000,0100,0200...FF00,0001,0101...)

此时有两种方法:

第一种是每次都通过接收到的序号来发送数据,就不需要改变蓝牙的发送和接收模式;

第二种是直接按照一定的间隔去发送数据;只要和硬件规定好时间就可以基本保证成功;

由于第一种方法的速度很慢,所以我选择的第二种方式;

(6)设置定时器,间隔时间20ms;由于是直接发送不需要返回所以选择CBCharacteristicWriteWithoutResponse的方式;

- (void)startSendData{

if (!sendTime) {

x = 0;

sendTime = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(sendData:) userInfo:nil repeats:YES];

}}

- (void)sendData:(NSTimer *)t{

Byte *Dvalue = (Byte *)[oadData bytes];

Byte byte[18];

for (int i = 0; i < 18; i++) {

if (i <= 1 ) {

byte[0] = x%256;

byte[1] = x/256;

}else{

if (i - 2 + x*16 < oadData.length) {

byte[i] = Dvalue[i - 2 + x*16];

}else{

byte[i] = 0xFF;

}}}

NSData *sendData = [NSData dataWithBytes:byte length:sizeof(byte)];

NSLog(@"\\n%ld - \\n%@",x,sendData);

[self.detailItem writeValue:sendData forCharacteristic:self.characteristic_oad_2 type:CBCharacteristicWriteWithoutResponse];

x++;

float sendValue = (float)x*16/(float)oadData.length;//进度条

self.textView.titleL.text = [NSString stringWithFormat:@"%.2f%%",sendValue*100];

[self.textView setCCCount:sendValue];

if (x*16 >= oadData.length) {//传输结束

[sendTime invalidate];

[self.textView setCCCount:1.0];

NSString *timeStr = [NSString stringWithFormat:@"升级完毕 时间%f",[[NSDate date] timeIntervalSinceDate:countTime]];

}}


【IOS】BLE-蓝牙空中升级(OAD)_第5张图片

(7)传输结束后,硬件设备会自启,蓝牙会断开;


【IOS】BLE-蓝牙空中升级(OAD)_第6张图片
【IOS】BLE-蓝牙空中升级(OAD)_第7张图片

demo没整理 见谅

https://github.com/huasali/blueToothDemo

你可能感兴趣的:(【IOS】BLE-蓝牙空中升级(OAD))