从 BLE 数据包中解压字节数组
Unpack byte array from BLE packet
我正在使用 BLE
开发应用程序,其中 iPhone 设备是 peripheral
,并将响应来自 Central
的 CBATTRequest
类型的写入请求.
我的看法是,这表示从 CBATTRequest
的值到 request.value
类型 NSData
的字节数组,我可以解压以读取 packet #
等 给定每个字段的大小(八位字节)和位置,我如何解包并读取每个值,conceptually
和 technically
?。 我将如何处理 constructing/packing 这个相同的字节数组,就像我准备发送此请求一样? 因为我必须以相同的方式打包数据以进行响应。
当您收到数据时,它可能在 CBATTRequest
中。数据包含在 NSData
类型的成员 value
中。成员 length
告诉 bytes/octects 中的长度。
CBATTRequest* request = ...;
NSData* value = request.value;
int packetLen = value.length;
然后将其转换为对应于数据包结构的 struct
是有意义的:
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];
Bit 4 to 0 set to 0x01 for..
这很可能与单个八位字节有关,例如至 ctrlCmd
。测试它:
if (((packet->ctrlCmd >> 0) & 0x1f) == 0x01) ...
0x1f
是 5 个连续位集(位 0 到 5)的位掩码。 >> 0
什么都不做,但如果位被移位则需要,例如对于第 2 位到第 5 位,您需要移动 2.
一个典型的 UUID 是 16 个字节长。所以我假设 byte index 13 & 12 指的是 16 字节 UUID 中的字节 12 和 13(因为只传输了两个字节)。剩余字节可能固定为基本蓝牙 UUID:
00000000-0000-1000-8000-00805F9B34FB
我正在使用 BLE
开发应用程序,其中 iPhone 设备是 peripheral
,并将响应来自 Central
的 CBATTRequest
类型的写入请求.
我的看法是,这表示从 CBATTRequest
的值到 request.value
类型 NSData
的字节数组,我可以解压以读取 packet #
等 给定每个字段的大小(八位字节)和位置,我如何解包并读取每个值,conceptually
和 technically
?。 我将如何处理 constructing/packing 这个相同的字节数组,就像我准备发送此请求一样? 因为我必须以相同的方式打包数据以进行响应。
当您收到数据时,它可能在 CBATTRequest
中。数据包含在 NSData
类型的成员 value
中。成员 length
告诉 bytes/octects 中的长度。
CBATTRequest* request = ...;
NSData* value = request.value;
int packetLen = value.length;
然后将其转换为对应于数据包结构的 struct
是有意义的:
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];
Bit 4 to 0 set to 0x01 for..
这很可能与单个八位字节有关,例如至 ctrlCmd
。测试它:
if (((packet->ctrlCmd >> 0) & 0x1f) == 0x01) ...
0x1f
是 5 个连续位集(位 0 到 5)的位掩码。 >> 0
什么都不做,但如果位被移位则需要,例如对于第 2 位到第 5 位,您需要移动 2.
一个典型的 UUID 是 16 个字节长。所以我假设 byte index 13 & 12 指的是 16 字节 UUID 中的字节 12 和 13(因为只传输了两个字节)。剩余字节可能固定为基本蓝牙 UUID:
00000000-0000-1000-8000-00805F9B34FB