基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬件通讯,传输图片
来源:互联网 发布:手机特效软件安卓版 编辑:程序博客网 时间:2024/04/19 05:33
因为公司产品需要,要写一个demo,演示iphone与硬件通过蓝牙通讯,传输数据包,折腾好久,终于折腾了出来了。分享一下实现的过程。
首先,要拿到苹果公司的MFI认证,然后要定义至少一种命令协议,让配件支持,Apple 并不负责提供协议的注册机制,制造商必须自己决定支持哪些协议,为了防止命名冲
突,协议的名字是反向的 DNS 字符串,类似com.apple.myProtocol
。
定义好协议后,要在工程中声明协议,在Info.plist的UISupportedExternalAccessoryProtocols键中声明。
工程里要添加ExternalAccessory 框架。
通过EAAccessoryManager获取配件列表,通过EAAccessory与配件建立连接,就可以创建一个EASession回话,与配件进行通讯
。
具体的可以参照苹果官方文档http://www.apple.com.cn/developer/library/ios/featuredarticles/ExternalAccessoryPT/Introduction/Introduction.html。
详细代码参照官方EADemo实例,里面实现的很清楚。
我的任务是将图片读进去,提取它的raw数据,但由于图片是96x96像素,就是说raw数据大小有96x96x4个bit,大约40k,输出到配件后要进行写入,速度太慢,所以将raw数
据经过处理,去掉透明度,RGB分别取5位,6位,5位,这样大约剩20k,即使这样也要将每个数据包分段发送,每段256个字节,发送数据前,加上一个文件头,每一段加上一个
段头,每一段发送之后等待硬件响应,响应之后才能发送下一段,1s之内没有接受响应则终止发送。部分代码如下:
UIImage *img=[UIImage imageNamed:myFilePath];//myFilePath位图片路径 CGImageRef cgimage=img.CGImage; CFDataRef dataref=CGDataProviderCopyData(CGImageGetDataProvider(cgimage));//获取图片cfdata数据 int cgdatalength=CFDataGetLength(dataref); UInt8 *pixelByteData=(UInt8 *)malloc(cgdatalength); CFDataGetBytes(dataref, CFRangeMake(0,cgdatalength),pixelByteData); int eachgroupnum=256;//每一段数据大小为256bit int groumpcount=cgdatalength/(eachgroupnum*2);//分段总数 NSMutableData *data1 = [NSMutableData data]; const char *buf = [self.ID UTF8String];//将命令头处理为字节流 if (buf) { uint32_t len = strlen(buf); char singleNumberString[3] = {'\0', '\0', '\0'}; uint32_t singleNumber = 0; for(uint32_t i = 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_t tmp = (uint8_t)(singleNumber & 0x000000FF); [data1 appendBytes:(void *)(&tmp) length:1]; } else { break; } } } [data1 appendBytes:(void *)(&groumpcount) length:1];//将分段总数添加到字节流中 [[EADSessionController sharedController] writeData:data1];//发送文件头 //将图片字节流数据分成groumpcount分,每个像素点去掉透明体,3字节RGB处理成2字节,读入字节流缓冲区 NSMutableData *datas = [NSMutableData data]; UInt16 temp=0; for(int i=0;i<groumpcount;i++) { [datas appendBytes:(void *)(&i) length:1];//段首编号部分 [datas appendBytes:(void *)(&groumpcount) length:1];//段首编号分段总数部分 for(int j=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_t tmp1 = (uint8_t)(temp & 0x0000FF00); uint8_t tmp2 = (uint8_t)(temp & 0x000000FF); [datas appendBytes:(void *)(&tmp1) length:1]; [datas appendBytes:(void *)(&tmp2) length:1]; } if (i==0) { [[EADSessionController sharedController] writeData:datas];//第一段数据直接发送 } else{ if(readdatabuf==0xff0000){//readdatabuf为硬件响应发回的数据,当以一段数据成功接受后,给应用发回0xff0000,且readdatabuf值存储最后 一次硬件响应 [[EADSessionController sharedController] writeData:datas];//发送下一段数据 readdatabuf=0;//清空上一次接受的数据 [datas setData:nil];//清空上一次发送的数据 continue;//结束本次循环 } [self performSelector:@selector(laterwritedata:) withObject:datas afterDelay:1]; if(temp==NO) { break;//1s之内没有收到硬件的响应,跳出循环,终止发送 } } readdatabuf=0;//清空上一次接受的数据 [datas setData:nil];//清空上一次发送的数据 }-(void) laterwritedata:(NSMutableData *)data{ if(readdatabuf==0xff0000){ temps=YES;//temp位YES,表示已得到响应,可以进行下一段的发送 [[EADSessionController sharedController] writeData:data]; } else { temps=NO; }}
- 基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬件通讯,传输图片
- 基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬件通讯,传输图片
- EAAccessory iphone与经过苹果MFI授权认证的硬件通讯
- IPhone MFI蓝牙认证分析
- 苹果MFI认证流程
- 苹果MFi认证
- Android SPP蓝牙传输
- Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块
- 蓝牙笔和手机通过蓝牙协议的通讯
- android 蓝牙 spp协议
- OIDC–基于OAuth2的下一代身份认证授权协议
- android 蓝牙SPP协议通信
- Android开发之蓝牙(一)——基于SPP协议蓝牙模块通信
- 买苹果配件什么最靠谱 认识苹果MFi认证
- 关于: 安卓能否与iphone通过蓝牙4.0(BLE)通讯?
- 使用安卓* 电话通过英特尔® Edison的蓝牙串行端口 (SPP) 与Arduino代码通信
- 基于ARM Linux的图像采集与蓝牙传输
- 树莓派 3B+ 原生蓝牙与手机通讯(BlueTooth SPP)方法和步骤
- WebRTC源码分析4_AVI文件读写
- python _自动化性能测试脚本
- git remote
- 动态规划基础
- 弱校ACM奋斗史
- 基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬件通讯,传输图片
- 获得双卡simCard信息
- 随想录(为什么循环队列具有先天的并行性)
- SICP习题解答1.40-1.46
- android recorder录音机的一些问题
- PowerBuilder学习笔记(1)PowerScript语言
- day31_ajax
- ajax实例--get提交方式
- 读书笔记---(1)