on peripheral:didReceiveWriteRequest
a CBATTRequest
returns hex-encoded
NSData
via request.value
.
This is what I have tried
// 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);
}
Console
pktNo: 121, cmd: 202, tx: 130, uuid: 48321, payload: 21421
First, these numbers look inaccurate, and I'm uncertain about what format this is even in, since the following analogous values I got from debugging tool don't seem to match.
Default: raw strings?
packet Packet * 0x281af0cc0 0x0000000281af0cc0
pktNo UInt8 'y'
ctrlCmd UInt8 '\xca'
txPowerRequest UInt8 '\x82'
uuid UInt16 48321
userPayload UInt16 21421
The hex string representation of your NSData
is apparently:
<79ca82c1 bcad530e 016a1435 127993ee 01ef7579>
That translates to:
So, you can use:
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt8 userPayload[15];
} Packet;
Which you can populate with:
Packet packet = {};
assert(data.length == sizeof(Packet));
memcpy(&packet, data.bytes, sizeof(Packet));
Note, I didn’t just set the packet to a pointer to the bytes
of the NSData
, because if the NSData
is deallocated, you don’t want to use a pointer to that deallocated memory. Instead, copy the bytes
to your packet
struct (perhaps checking to make sure the two match in size).
In the interest of full disclosure, the above makes a somewhat cavalier assumption that endianness of the payload matches that of device running your app. You theoretically might want to make the UUID a UInt8 uuid[2]
, instead, and then if you need the UUID value, recalculate it from those two octets.