因為公司產(chǎn)品需要,要寫一個demo,演示iphone與硬件通過藍牙通訊,傳輸數(shù)據(jù)包,折騰好久,終于折騰了出來了。分享一下實現(xiàn)的過程。
首先,要拿到蘋果公司的MFI認證,然后要定義至少一種命令協(xié)議,讓配件支持,Apple 并不負責提供協(xié)議的注冊機制,制造商必須自己決定支持哪些協(xié)議,為了防止命名沖
突,協(xié)議的名字是反向的 DNS 字符串,類似com.apple.myProtocol。
定義好協(xié)議后,要在工程中聲明協(xié)議,在Info.plist的UISupportedExternalAccessoryProtocols鍵中聲明。
????? 工程里要添加ExternalAccessory 框架。
通過EAAccessoryManager獲取配件列表,通過EAAccessory與配件建立連接,就可以創(chuàng)建一個EASession回話,與配件進行通訊。
具體的可以參照蘋果官方文檔http://www.apple.com.cn/developer/library/ios/featuredarticles/ExternalAccessoryPT/Introduction/Introduction.html。
????? 詳細代碼參照官方EADemo實例,里面實現(xiàn)的很清楚。
????? 我的任務是將圖片讀進去,提取它的raw數(shù)據(jù),但由于圖片是96x96像素,就是說raw數(shù)據(jù)大小有96x96x4個bit,大約40k,輸出到配件后要進行寫入,速度太慢,所以將raw數(shù)
據(jù)經(jīng)過處理,去掉透明度,RGB分別取5位,6位,5位,這樣大約剩20k,即使這樣也要將每個數(shù)據(jù)包分段發(fā)送,每段256個字節(jié),發(fā)送數(shù)據(jù)前,加上一個文件頭,每一段加上一個
段頭,每一段發(fā)送之后等待硬件響應,響應之后才能發(fā)送下一段,1s之內(nèi)沒有接受響應則終止發(fā)送。部分代碼如下:
UIImage?*img=[UIImage?imageNamed:myFilePath];//myFilePath位圖片路徑??
CGImageRefcgimage=img.CGImage;??
CFDataRefdataref=CGDataProviderCopyData(CGImageGetDataProvider(cgimage));//獲取圖片cfdata數(shù)據(jù)??
intcgdatalength=CFDataGetLength(dataref);??
UInt8?*pixelByteData=(UInt8?*)malloc(cgdatalength);??
????CFDataGetBytes(dataref,?CFRangeMake(0,cgdatalength),pixelByteData);??
inteachgroupnum=256;//每一段數(shù)據(jù)大小為256bit??
intgroumpcount=cgdatalength/(eachgroupnum*2);//分段總數(shù)??
NSMutableData?*data1?=?[NSMutableData?data];??
const?char?*buf?=?[self.ID?UTF8String];//將命令頭處理為字節(jié)流??
????if?(buf) ?{ ?
? ? ? uint32_tlen?=?strlen(buf);??
? ? char?singleNumberString[3]?=?{'\0',?'\0',?'\0'};??
? ? uint32_tsingleNumber?=?0;??
for(uint32_ti?=?0?;?i?<?len;?i+=2) ? { ?
? ? ?if?(?((i+1)<?len)?&&?isxdigit(buf[i])?&&?(isxdigit(buf[i+1]))?) ?{
? ? ? ? ? ? ? ?singleNumberString[0]?=?buf[i]; ?
????????????????singleNumberString[1]?=?buf[i?+?1];??
????????????????sscanf(singleNumberString,?"%x",?&singleNumber);??
uint8_ttmp?=?(uint8_t)(singleNumber?&?0x000000FF);??
????????????????[data1?appendBytes:(void?*)(&tmp)?length:1];??
????????????}??
????????????else??
????????????{??
????????????????break;??
????????????}??
????????}??
????}??
????[data1?appendBytes:(void?*)(&groumpcount)?length:1];//將分段總數(shù)添加到字節(jié)流中??
????[[EADSessionController?sharedController]?writeData:data1];//發(fā)送文件頭??
????//將圖片字節(jié)流數(shù)據(jù)分成groumpcount分,每個像素點去掉透明體,3字節(jié)RGB處理成2字節(jié),讀入字節(jié)流緩沖區(qū)??
NSMutableData?*datas?=?[NSMutableData?data];??
UInt16temp=0;??
for(inti=0;i<groumpcount;i++)??
????{??
???????[datas?appendBytes:(void?*)(&i)?length:1];//段首編號部分??
???????[datas?appendBytes:(void?*)(&groumpcount)?length:1];//段首編號分段總數(shù)部分??
for(intj=eachgroupnum*i*2;j<eachgroupnum*(i+1)*2;j=j+4)??
????????{??
temp=pixelByteData[j+2];??
???????????temp+=pixelByteData[j+1]*32;??
???????????temp+=pixelByteData[j]*2048;??
uint8_ttmp1?=?(uint8_t)(temp?&?0x0000FF00);??
uint8_ttmp2?=?(uint8_t)(temp?&?0x000000FF);??
???????????[datas?appendBytes:(void?*)(&tmp1)?length:1];??
???????????[datas?appendBytes:(void?*)(&tmp2)?length:1];??
?????????}??
if?(i==0)?{??
????????????[[EADSessionController?sharedController]?writeData:datas];//第一段數(shù)據(jù)直接發(fā)送??
????????}??
????????else{??
if(readdatabuf==0xff0000){//readdatabuf為硬件響應發(fā)回的數(shù)據(jù),當以一段數(shù)據(jù)成功接受后,給應用發(fā)回0xff0000,且readdatabuf值存儲最后?一次硬件響應??
????????????????[[EADSessionController?sharedController]?writeData:datas];//發(fā)送下一段數(shù)據(jù)??
? ? ? ? ? ? ? ? readdatabuf=0;//清空上一次接受的數(shù)據(jù)??
????????????????[datas?setData:nil];//清空上一次發(fā)送的數(shù)據(jù)??
????????????????continue;//結(jié)束本次循環(huán)??
????????????}??
????????????[self?performSelector:@selector(laterwritedata:)?withObject:datas?afterDelay:1];??
if(temp==NO)??
????????????{??
????????????????break;//1s之內(nèi)沒有收到硬件的響應,跳出循環(huán),終止發(fā)送??
????????????}??
????????}??
? ? ? ? readdatabuf=0;//清空上一次接受的數(shù)據(jù)??
????????[datas?setData:nil];//清空上一次發(fā)送的數(shù)據(jù)??
????}??
-(void)?laterwritedata:(NSMutableData?*)data??
{??
if(readdatabuf==0xff0000){??
? ? ? ? ? ? ? ?temps=YES;//temp位YES,表示已得到響應,可以進行下一段的發(fā)送??
? ? ? ? ? ? ? [[EADSessionController?sharedController]?writeData:data];??
????????}??
????????else??
????????{??
? ? ? ? ? ? ? ?temps=NO;??
????????} ?
} ?