首页 > 解决方案 > 提取 4 位与 2 位蓝牙 HEX 数据,为什么相同的方法会导致错误

问题描述

这是来自此 SO(提取 4 位蓝牙 HEX 数据)的后续问题,答案已被接受。我想更多地了解为什么我使用的是什么;下面的例子;(有效)当应用于 SO(提取 4 位蓝牙 HEX 数据)时无效。

要解码循环功率数据,前 2 位是标志,用于确定功率计提供的功能。

guard let characteristicData = characteristic.value else { return -1 }
var byteArray = [UInt8](characteristicData)
// This is the output from the Sensor (In Decimal and Hex)
// DEC [35,  0, 25,  0, 96, 44, 0, 33, 229] Hex:{length = 9, bytes = 0x23001900602c0021e5} FirstByte:100011    

/// First 2 Bits is Flags
let flags = byteArray[1]<<8 + byteArray[0]

这导致该flags位与前 2 位连接。之后我使用该flags位并将其屏蔽以获取相关位位置。

例如:为了获得权力平衡,我愿意(flags & 0x01 > 0) 在此处输入图像描述

这种方法有效,我是一个快乐的露营者。

但是,为什么当我在 SO Extract 4 bits of Bluetooth HEX Data上使用相同的方法时它不起作用?这是解码蓝牙 FTMS 数据(与上面不同)

guard let characteristicData = characteristic.value else { return -1 }
let byteArray = [UInt8](characteristicData)
let nsdataStr = NSData.init(data: (characteristic.value)!)

print("pwrFTMS 2ACC Feature  Array:[\(byteArray.count)]\(byteArray) Hex:\(nsdataStr)")

PwrFTMS 2ACC Feature Array:[8][2, 64, 0, 0, 8, 32, 0, 0] Hex:{length = 8, bytes = 0x0240000008200000}

根据规范,返回的数据有 2 个特征,每个特征 4 个八位字节长。

在此处输入图像描述

正在做

byteArray[3]<<24 + byteArray[2]<<16 + byteArray[1]<<8 + byteArray[0]

加入前 4 个字节会导致错误的输出开始解码。

编辑:添加说明

标签: iosswiftxcodecore-bluetooth

解决方案


你说的这段代码有问题......但它似乎“意外地”工作:

let flags = byteArray[1]<<8 + byteArray[0]

这导致 a UInt8,但第一个表中的标志字段是 16 位。请注意,byteArray[1] << 8始终计算为0,因为您将字节的所有位移出字节。它似乎有效,因为您唯一感兴趣的部分是byteArray[0].

因此,您需要先将其转换为 16 位(或更大),然后再对其进行转换:

let flags = (UInt16(byteArray[1]) << 8) + UInt16(byteArray[0])

现在flagsUInt16

同样,当您执行 4 个字节时,您需要它们是 32 位值,然后再进行移位。所以

let flags = UInt32(byteArray[3]) << 24 
    + UInt32(byteArray[2]) << 16
    + UInt32(byteArray[1]) << 8
    + UInt32(byteArray[0])

但由于这只是从以小端字节顺序排列的字节序列中读取 32 位值,并且所有当前的 Apple 设备(以及绝大多数其他现代计算机)都是小端机器,因此这是一种更简单的方法:

let flags = byteArray.withUnsafeBytes {
    $0.bindMemory(to: UInt32.self)[0]
}

总之,在这两种情况下,您只在移位加法中保留了字节 0,因为由于将位完全移出字节,其他移位全部评估为 0。碰巧在第一种情况下 byte[0] 包含您需要的信息。一般来说,有必要首先将值提升到结果所需的大小,然后再对其进行移位。


推荐阅读