蓝牙指令解析

蓝牙指令解析

本篇从如下三个方面介绍通过data如何与蓝牙进行通讯。

  • 字节高低位及运算
  • 蓝牙特征的属性及作用
  • CRC16校验常用算法及实现

字节高低位及运算

1byte的范围为0-255,两个16进制的字符表示的范围(15*16+15)为0~255,故一字节等于两个16进制的字符.

字节高低位的概念

蓝牙通信规约中,一般会说明一个信息占用多少个字节,同时会说明高位在前还是低位在前。
一般,字节的表示都是高位在前,低位在后。
如:一个16位的字符,高位和低位各占8位,前8位为高位的字节,后8位为低位的字节;
32位的字符高位和低位各占16字节,前16位为高位的字节,后16位为低位的字节。

大小端模式
  • 大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中
  • 小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
字节高低位的运算
  • 字节高低位的运算主要使用的是位运算。根据字节所在的位置,运算相应的字节数得到具体的int值。
    例:1字节的运算,分为高低各4位。

    • 1字节等于2个16进制的字符:0xDA
    • 高字节在前:
      • 第一个16进制字符表示高4位。D的大小:(D << 4) & 0xFF,int类型。移动到高位再计算大小
      • 第二个16进制字符表示低4位。A的大小:A & 0xFF,int类型。
    • 低字节在前:
      • 第一个16进制字符表示低4位。D的大小:D & 0xFF,int类型。
      • 第二个16进制字符表示高4位。A的大小:(A << 4) & 0xFF,int类型。移动到高位再计算大小
  • 有时候一个数据区间>1 byte,需要计算这部分的大小,即各个位置上的byte值相加(64位CPU):
    如:4byte值的计算:0x4A5D434F

    • 第一位的值:4F & 0xFF
    • 第二位的值:(43 << 8 ) & 0xFF
    • 第三位的值:(5D << 16) & 0xFF
    • 第四位的值: (4A << 32) & 0xFF
    • 将各位置上的值相加,即为此数据区间的值。

蓝牙特征属性

基本蓝牙的使用就不介绍了,这里说下蓝牙服务中特征的属性,不同的特征属性对蓝牙的通信模式影响很大。
iOS中的蓝牙特征属性值如下:

typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
	CBCharacteristicPropertyBroadcast												= 0x01,
	CBCharacteristicPropertyRead													= 0x02,
	CBCharacteristicPropertyWriteWithoutResponse									= 0x04,
	CBCharacteristicPropertyWrite													= 0x08,
	CBCharacteristicPropertyNotify													= 0x10,
	CBCharacteristicPropertyIndicate												= 0x20,
	CBCharacteristicPropertyAuthenticatedSignedWrites								= 0x40,
	CBCharacteristicPropertyExtendedProperties										= 0x80,
	CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(10_9, 6_0)	= 0x100,
	CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(10_9, 6_0)	= 0x200
};

我们调试蓝牙的时候,特别需要注意的属性为这几个,它们关系到特征的作用,进而影响功能的实现。

    // 读特征,读取蓝牙传输的数据
    CBCharacteristicPropertyRead, 
    // 写特征,数据写入蓝牙后蓝牙不回复是否写入成功
	CBCharacteristicPropertyWriteWithoutResponse,
	// 写特征,数据写入蓝牙后蓝牙会回复是否写入成功,调用相关的代理方法获取
	CBCharacteristicPropertyWrite,
	// 订阅特征,蓝牙会主动回传消息。订阅有订阅成功失败的代理,以及获取订阅消息的代理方法
	CBCharacteristicPropertyNotify,

可以写数据的特征的不同属性,直接影响写数据方法的调用。

typedef NS_ENUM(NSInteger, CBCharacteristicWriteType) {
	CBCharacteristicWriteWithResponse = 0,
	CBCharacteristicWriteWithoutResponse,
};

// 给外设写数据的方法,type要根据特征的属性来设置
- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;

CRC校验

CRC校验:循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
百科详解

在蓝牙指令传输中,通常会在数据的末尾进行CRC校验,和公司硬件端采用同样的算法即可。

蓝牙指令解析举例说明

简单的蓝牙通讯协议

简单的通讯协议说明如下,基本都大同小异,高字节在前,低字节在后:

类型字节大小说明
同步头4字节同步头一般是固定的4个字节
报文长度2字节除了同步头之外其他数据的大小,每次传输时都要进行计算
命令字2字节此例中为0x00 0x00
功能码2字节此例中为0x00 0x00
数据正文动态字节长度计算出报文长度后减去固定字节区域后的数据
校验CRC162字节报文长度开始至动态部分结束,及不含同步头和校验码的数据进行校验后的值

这个报文结构比较简单,实际中可根据需要自由添加不同区间的功能码及字节数。

解析协议
  • 订阅特征后,接收到蓝牙数据4a4a4a4a000c000000004a5d6b3c1234
  • 根据上面的协议可知:各区域字节代表的含义。
  • 计算报文长度:(00 << 8) & 0xFF + 0c & 0xFF = 12;
  • 此数据类型为NSData,通过NSDatasubdataWithRange:进行数据的截取。
  • 数据解析过程中需要用到各种转换。基本的转换为data和16进制字符串互相转换。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值