1

我正在使用来自 google ( BluetoothLeGatt ) 的示例项目从 BLE 设备接收数据,并尝试读取其 scanRecord 中的特定字节,该 scanRecord 是通过onLeScan方法获得的。

我的问题是我在网络中观察到的数据与我在日志中看到的数据不匹配。

这是在 Android 4.3 上使用三星 Galaxy S4 进行测试的。为了验证 Android 上的 scanRecord 日志是否正确,我使用 TI 的 Packet Sniffer 来观察设备正在广播的字节流,如下所示: 在此处输入图像描述

即设备正在向网络广播 31 字节的数据,并且周围没有其他工作设备。

02 01 1A 1A FF 4C 00 02 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C C6 64

另一方面,Android 日志声称正在接收的数据长度为 62 字节,并且它与数据匹配直到第 29 个 [0-indexed] 字节,其余数据为 0。

02-12 15:34:09.548: D/DEBUG(26801): len: 62 data:02011a1aff4c000215000000000000000000000000000000000000000cc60000000000000000000000000000000000000000000000000000000000000000

这是我用来在LeScanCallback方法中获取日志的代码片段:

int len = scanRecord.length;
String scanHex = bytesToHex(scanRecord);
Log.d("DEBUG", "len: " + len + " data:" + scanHex);

用于将字节数组转换为十六进制表示的方法:

private static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for ( int j = 0; j < bytes.length; j++ ) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    } 

我使用了其他一些示例项目,包括 Dave Smith 的示例和 RadiusNetworks 的Android iBeacon 库,最终得到了相同的结果。我无法理解为什么当“Packet Sniffer”显示(我也知道)它应该是 31 个字节时,我收到 62 个字节的数据。如果我能够正确读取最后一个字节中的数据(我从 Android 的 BluetoothAdapter获得00而不是64 ),这将不是我主要关心的问题。但事实也并非如此。

对于数据(仅最后一个字节)和 Android 接收到的数据与网络上实际存在的数据之间的数据大小不匹配的潜在原因,我将不胜感激。

4

1 回答 1

2

您的传输格式不正确,包含 31 个字节的有效负载数据(PDU 长度为 37),而其内部长度字段表明它总共应仅包含 30 个字节(PDU 长度为 36)。

让我们看看你的数据

02 01 1a

这是类型代码的长度 (2) - 01 和 1a,到目前为止还不错

1a ff 4c ...

现在我们遇到了一个问题 - 1a 是该字段(制造商特定数据)的长度代码,值为 26。但在您的情况下,后面有 27 个字节的数据,而不是您指示您将提供的正确的 26 个字节。

现在,如果您有一个格式正确的数据包,您仍然会得到一个更大的缓冲区,在正确的内容之后填充无意义(可能未初始化)的值,但是您可以通过根据字段长度值解析缓冲区并忽略它来简单地忽略它任何未在声明的长度中考虑的内容。

但是对于您当前的格式错误的数据包,将数据包数据复制到缓冲区的过程会在声明的内容大小处停止,并且未通知的额外字节永远不会进入您的程序接收的缓冲区 - 所以您会看到一些随机的东西,就像其余的一样未使用的长度。

可能,当您编写全零“区域 UUID”(可能想要重新考虑)时,您只需输入一个额外的字节......

于 2014-02-12T16:12:24.930 回答