美文网首页
基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬

基于SPP协议,通过iphone蓝牙与经过苹果MFI授权认证的硬

作者: 余鹤龄 | 来源:发表于2020-08-19 11:11 被阅读0次

    因为公司产品需要,要写一个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位图片路径  

    CGImageRefcgimage=img.CGImage;  

    CFDataRefdataref=CGDataProviderCopyData(CGImageGetDataProvider(cgimage));//获取图片cfdata数据  

    intcgdatalength=CFDataGetLength(dataref);  

    UInt8 *pixelByteData=(UInt8 *)malloc(cgdatalength);  

        CFDataGetBytes(dataref, CFRangeMake(0,cgdatalength),pixelByteData);  

    inteachgroupnum=256;//每一段数据大小为256bit  

    intgroumpcount=cgdatalength/(eachgroupnum*2);//分段总数  

    NSMutableData *data1 = [NSMutableData data];  

    const char *buf = [self.ID UTF8String];//将命令头处理为字节流  

        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];//将分段总数添加到字节流中  

        [[EADSessionController sharedController] writeData:data1];//发送文件头  

        //将图片字节流数据分成groumpcount分,每个像素点去掉透明体,3字节RGB处理成2字节,读入字节流缓冲区  

    NSMutableData *datas = [NSMutableData data];  

    UInt16temp=0;  

    for(inti=0;i<groumpcount;i++)  

        {  

           [datas appendBytes:(void *)(&i) length:1];//段首编号部分  

           [datas appendBytes:(void *)(&groumpcount) length:1];//段首编号分段总数部分  

    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];//第一段数据直接发送  

            }  

            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授权认证的硬

          本文链接:https://www.haomeiwen.com/subject/yddqjktx.html