基于SPP協(xié)議,通過iphone藍牙與經(jīng)過蘋果MFI授權認證的硬件通訊,傳輸圖片

因為公司產(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;??

????????} ?

} ?


?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容