【IOS】BLE-藍牙空中升級(OAD)

藍牙為CC2541 ios升級藍牙固件;

1.頭文件

#import <CoreBluetooth/CoreBluetooth.h>

升級要用到的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.獲取藍牙列表,選擇需要升級的藍牙


3.獲取所有的特征值,找到我們需要的通道,設(shè)置通道的模式為監(jiān)測通道變化

[peripheral setNotifyValue:YES forCharacteristic:characteristic];

傳過去所需的參數(shù)

[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




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];

}

6.開始進行藍牙升級:

(1)發(fā)送一個字節(jié)數(shù)據(jù)來獲取藍牙設(shè)備的當前設(shè)備信息

- (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)在代理處接收返回數(shù)據(jù)

- (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)處理接收的數(shù)據(jù),如果版本不相同,就把本地文件的固件信息通過通道1發(fā)送過去;

固件信息包含的信息有:固件版本寥枝、固件長度葱弟、固件類型

- (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]};//本地數(shù)據(jù)的固件信息

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)在代理處接收返回數(shù)據(jù)(如果成功會通過通道2返回數(shù)據(jù))

- (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)處理數(shù)據(jù),開始發(fā)送本地文件;收到的數(shù)據(jù)是需要發(fā)送數(shù)據(jù)的序號(0000-FFFF,高位在后;0000,0100,0200...FF00,0001,0101...)

此時有兩種方法:

第一種是每次都通過接收到的序號來發(fā)送數(shù)據(jù),就不需要改變藍牙的發(fā)送和接收模式;

第二種是直接按照一定的間隔去發(fā)送數(shù)據(jù);只要和硬件規(guī)定好時間就可以基本保證成功;

由于第一種方法的速度很慢,所以我選擇的第二種方式;

(6)設(shè)置定時器,間隔時間20ms;由于是直接發(fā)送不需要返回所以選擇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) {//傳輸結(jié)束

[sendTime invalidate];

[self.textView setCCCount:1.0];

NSString *timeStr = [NSString stringWithFormat:@"升級完畢 時間%f",[[NSDate date] timeIntervalSinceDate:countTime]];

}}


(7)傳輸結(jié)束后,硬件設(shè)備會自啟,藍牙會斷開;



demo沒整理 見諒

https://github.com/huasali/blueToothDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幔托,居然都是意外死亡,警方通過查閱死者的電腦和手機蜂挪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門重挑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棠涮,你說我怎么就攤上這事谬哀。” “怎么了严肪?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵史煎,是天一觀的道長。 經(jīng)常有香客問我驳糯,道長篇梭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任酝枢,我火速辦了婚禮恬偷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帘睦。我一直安慰自己袍患,他們只是感情好坦康,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诡延,像睡著了一般滞欠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肆良,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天仑撞,我揣著相機與錄音,去河邊找鬼妖滔。 笑死,一個胖子當著我的面吹牛桶良,可吹牛的內(nèi)容都是我干的座舍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陨帆,長吁一口氣:“原來是場噩夢啊……” “哼曲秉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疲牵,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤承二,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纲爸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亥鸠,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年识啦,在試婚紗的時候發(fā)現(xiàn)自己被綠了负蚊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡颓哮,死狀恐怖家妆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冕茅,我是刑警寧澤伤极,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站姨伤,受9級特大地震影響哨坪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜姜挺,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一齿税、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炊豪,春花似錦凌箕、人聲如沸拧篮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽串绩。三九已至,卻和暖如春芜壁,著一層夾襖步出監(jiān)牢的瞬間礁凡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工慧妄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顷牌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓塞淹,卻偏偏與公主長得像窟蓝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子饱普,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容