问题
In basic terms, I am using nativescript for a cross platform application. This application interacts with BLE devices. The BLE devices send a scan response after the advertisement packet, which I am able to retrieve as an NSData object on the iOS side.
Here is the (pseudo) output from the description property: <54fca267 0b00>.
The output represents the hardware address of the peripheral.
The hardware guys are telling me this is in little-endian, and I know it is a 48-bit string. It is coming from the peripheral, which has its firmware written in C.
I have been trying for a few days to convert this into a string (with the correct endianness) so that I can store the hardware address on our back-end, but am unable to come up with an elegant solution.
One solution I did come up with was reading the :description property of the NSData object, and then manually (in javascript) 'decoding' it. I just do not feel like this solution is proper enough for a production environment, and would like to use native utilities instead.
I have tried using :
NSString.alloc().initWithDataEncoding(mac, NSUTF8StringEncoding);
..with every encoding type from THIS page of the documentation. I am either getting nil in return, or incorrect characters.
Like I previously stated, this is being written in NativeScript; however, I have a decent understanding of objective C, so I should be able to convert any examples provided in that language.
Any input would be greatly appreciated. Thanks in advance!
回答1:
CRD's answer is on the right track, but I'm guessing is not what you're asking for. You want a result that looks like "54:fc:a2:67:0b:00" (a Bluetooth/MAC address), right? Here's a simple, brute force approach (you could do this in a loop or the like, but not worth it IMO).
// Just for testing; you already have data.
uint8_t address[6] = { 0x54, 0xfc, 0xa2, 0x67, 0x0b, 0x00 };
NSData *data = [NSData dataWithBytes:address length:6];
// Check the length before proceeding (maybe return an error rather than crash :D)
assert([data length] == 6);
// Grab the bytes
const uint8_t *bytes = data.bytes;
// Format them
NSString *addressString = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]];
// 3. Profit
NSLog(@"%@", addressString);
But....
I'm not quite certain what the engineer means here by "little-endian." 54:fc:a2 isn't an assigned manufacturer code. Typically, I would assume "little-endian" means that they've byte-swapped the 16-bit words (which I've run into on CSR platforms), and so this should be fc:54:67, but that isn't assigned either. Treating the whole thing as completely backwards gives us 00:0b:67 which is assigned to TopView, who makes Bluetooth cameras, so I'm betting that's what "little-endian" means here (which makes sense, because the normal way to write MAC addresses on the wire is exactly backwards of that, and is "big-endian").
So that would change the code to:
NSString *addressString = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]];
Is the address 00:b0:67:a2:fc:54?
回答2:
You appear to have an NSData
object containing 6 bytes, the first byte is the least significant one (little-endian). Don't try to use the character representation, this is binary data, process it as such.
Use the bytes
property of NSData
to get a pointer to the first byte and save it to an Byte *
variable, say, bPtr
. Now just index the bytes in turn and insert them into a 64-bit unsigned integer variable in order. You can do this by bit shifting the integer and or'ing in the next byte - start at bPtr[5]
down to bPtr[0]
and shift the integer left 8 each time.
HTH
来源:https://stackoverflow.com/questions/46504035/little-endian-byte-order-ios-ble-scan-response