Ios 从BLE数据包中解包字节数组

Ios 从BLE数据包中解包字节数组,ios,objective-c,bitmap,bit-manipulation,Ios,Objective C,Bitmap,Bit Manipulation,我正在使用BLE开发一个应用程序,其中iPhone设备是外围设备,并将响应中央设备发出的CBATTRequest类型的写入请求 我的理解是,这表示一个字节数组,从CBATTRequest的值通过request.value类型NSData,我可以解压以读取packet等。鉴于每个字段的大小(八位字节)和位置,我如何解压和读取每个值,概念上和技术上?。而且如果我准备发送这个请求,我将如何构建/打包这个相同的字节数组?因为我必须以相同的方式打包响应数据 当您收到数据时,它可能位于CBATTReques

我正在使用
BLE
开发一个应用程序,其中iPhone设备是
外围设备
,并将响应
中央设备发出的
CBATTRequest
类型的写入请求


我的理解是,这表示一个字节数组,从
CBATTRequest
的值通过
request.value
类型
NSData
,我可以解压以读取
packet
等。鉴于每个字段的大小(八位字节)和位置,我如何解压和读取每个值,
概念上
技术上
?。而且如果我准备发送这个请求,我将如何构建/打包这个相同的字节数组?因为我必须以相同的方式打包响应数据

当您收到数据时,它可能位于
CBATTRequest
中。数据包含在类型为
NSData
的成员
值中。成员
length
以字节/八位字节表示长度

CBATTRequest* request = ...;
NSData* value = request.value;
int packetLen = value.length;
然后将其转换为与数据包结构相对应的
结构是有意义的:

struct Packet {
    unsgined char pktNo;
    unsigned char ctrlCmd;
    unsigned char txPowerRequest;
    unsigned char uuid[2];
    unsigned char txCnt;
    unsigned char userPayload[14];
};

Packet* packet= (Packet)value.bytes;
请注意,数据包的长度是可变的。因此,只有部分
userPayload
是有效的。有效长度为:

int userPayloadLength = packetLen - 6;
现在,您可以轻松访问成员:

int packetNumber = packet->pktNo;
要构造一个类似的数据包,您将使用稍微类似的方法

Packet reponse;
response.pktNo = ...;
reponse.ctrlCmd = ...;
int userPayloadLength = 5;
NSData* value = [NSData dataWithBytes: &response length: userPayloadLength + 6];
位4到0设置为0x01,用于

这很可能是相对于单个八位元,例如to
ctrlCmd
。要测试它,请执行以下操作:

if (((packet->ctrlCmd >> 0) & 0x1f) == 0x01) ...
0x1f
是5个连续位集(位0到5)的位掩码<代码>>>0
不执行任何操作,但如果位被移位,则需要执行此操作,例如,对于位2到5,您需要移位2

典型的UUID长度为16字节。所以我假设字节索引13&12指16字节UUID中的字节12和13(因为只传输两个字节)。其余字节可能固定在基本蓝牙UUID上:

00000000-0000-1000-8000-00805F9B34FB

您好,我成功地从中央接收请求,并将值打印到控制台。我想实现我从你的答案中学到的东西,但整数文本太大,无法分配给游乐场中的数据类型。
整数文本存储在int
中时溢出。以下是数据示例:
确实发送了写入请求“
。还有,关于你最初的答案,我不确定为什么要从
数据包长度中减去
6
,将5设置为
userPayloadLength
,然后再将
6
添加到
长度。这些数字来自哪里?正如您可能注意到的那样,争用位对我来说是新的,因此任何深入研究这一点的资源都将受到赞赏。6是数据包固定部分的长度,因此是到可变部分开始的偏移量。所以总长度总是6加上可变部分的长度。5只是一个例子。n-6用于从总长度推导可变零件长度。n+6用于从可变部分长度中减去总长度。操场仅为快速,对吗?所以你突然在谈论不同的代码。你最好打开一个新问题并添加相关代码。不,相同的代码。将转换为swift作为游乐场,因此我不必在测试时重新运行应用程序。这应该是可能的。当我将示例中的数据分配给变量时,它会溢出。也许我应该将其视为十六进制字符串,并定义为“0x7c1085004c1ab…”。我知道如果直接使用“request.value”中的值,则不会出现此问题。@Codo顺便说一句,当我试图通过
response.userPayload=packet->userPayload为
userPayload
赋值时
I get error
数组类型“UInt8[15]”不可分配
,即使分配的值不是来自原始数据包,仍然会发生。@Codo Id希望尝试此操作,但并非所有值都是
UInt8
const unsigned char responseData[]={packet->pktNo,packet->ctrlCmd,packet->txPowerRequest}