解压十六进制编码的 NSData
Unpack hex-encoded NSData
在 peripheral:didReceiveWriteRequest
上 CBATTRequest
returns hex-encoded
NSData
通过 request.value
。
这是我试过的
// Define struct
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt16 userPayload; // how to store 15 octets?
} Packet;
// Unpack
Packet *packet = (Packet *)request.value.bytes;
if (packet) {
UInt8 pktNo = packet->pktNo;
UInt8 cmd = packet->ctrlCmd;
UInt8 tx = packet->txPowerRequest;
UInt16 uuid = packet->uuid;
UInt16 payload = packet->userPayload;
NSLog(@"pktNo: %hhu, cmd: %hhu, tx: %hhu, uuid: %hu, payload: %hu", pktNo, cmd, tx, uuid, payload);
}
控制台
pktNo: 121, cmd: 202, tx: 130, uuid: 48321, payload: 21421
首先,这些数字看起来不准确,我什至不确定这是什么格式,因为我从调试工具获得的以下类似值似乎不匹配。
默认: 原始字符串?
packet Packet * 0x281af0cc0 0x0000000281af0cc0
pktNo UInt8 'y'
ctrlCmd UInt8 '\xca'
txPowerRequest UInt8 '\x82'
uuid UInt16 48321
userPayload UInt16 21421
您的 NSData
的十六进制字符串表示显然是:
<79ca82c1 bcad530e 016a1435 127993ee 01ef7579>
转换为:
- 0x79为PKT,十进制为121
- 0xca为CMD,十进制为202
- 0x82为TXP,十进制为130
- 0xbcc1为UUID,十进制为48321
- 有效载荷是 ad 53 0e 01 6a 14 35 12 79 93 ee 01 ef 75 79
因此,您可以使用:
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt8 userPayload[15];
} Packet;
您可以填充的内容:
Packet packet = {};
assert(data.length == sizeof(Packet));
memcpy(&packet, data.bytes, sizeof(Packet));
注意,我不只是将数据包设置为指向 NSData
的 bytes
的指针,因为如果 NSData
被释放,你不想使用指向该已释放内存的指针。相反,将 bytes
复制到您的 packet
结构(可能检查以确保两者大小匹配)。
为了全面披露,上面做了一个有点随意的假设,即有效负载的字节顺序与设备 运行 您的应用程序的字节顺序相匹配。理论上您可能希望将 UUID 设为 UInt8 uuid[2]
,然后如果您需要 UUID 值,请从这两个八位字节重新计算它。
在 peripheral:didReceiveWriteRequest
上 CBATTRequest
returns hex-encoded
NSData
通过 request.value
。
这是我试过的
// Define struct
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt16 userPayload; // how to store 15 octets?
} Packet;
// Unpack
Packet *packet = (Packet *)request.value.bytes;
if (packet) {
UInt8 pktNo = packet->pktNo;
UInt8 cmd = packet->ctrlCmd;
UInt8 tx = packet->txPowerRequest;
UInt16 uuid = packet->uuid;
UInt16 payload = packet->userPayload;
NSLog(@"pktNo: %hhu, cmd: %hhu, tx: %hhu, uuid: %hu, payload: %hu", pktNo, cmd, tx, uuid, payload);
}
控制台
pktNo: 121, cmd: 202, tx: 130, uuid: 48321, payload: 21421
首先,这些数字看起来不准确,我什至不确定这是什么格式,因为我从调试工具获得的以下类似值似乎不匹配。
默认: 原始字符串?
packet Packet * 0x281af0cc0 0x0000000281af0cc0
pktNo UInt8 'y'
ctrlCmd UInt8 '\xca'
txPowerRequest UInt8 '\x82'
uuid UInt16 48321
userPayload UInt16 21421
您的 NSData
的十六进制字符串表示显然是:
<79ca82c1 bcad530e 016a1435 127993ee 01ef7579>
转换为:
- 0x79为PKT,十进制为121
- 0xca为CMD,十进制为202
- 0x82为TXP,十进制为130
- 0xbcc1为UUID,十进制为48321
- 有效载荷是 ad 53 0e 01 6a 14 35 12 79 93 ee 01 ef 75 79
因此,您可以使用:
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt8 userPayload[15];
} Packet;
您可以填充的内容:
Packet packet = {};
assert(data.length == sizeof(Packet));
memcpy(&packet, data.bytes, sizeof(Packet));
注意,我不只是将数据包设置为指向 NSData
的 bytes
的指针,因为如果 NSData
被释放,你不想使用指向该已释放内存的指针。相反,将 bytes
复制到您的 packet
结构(可能检查以确保两者大小匹配)。
为了全面披露,上面做了一个有点随意的假设,即有效负载的字节顺序与设备 运行 您的应用程序的字节顺序相匹配。理论上您可能希望将 UUID 设为 UInt8 uuid[2]
,然后如果您需要 UUID 值,请从这两个八位字节重新计算它。