在Android中阅读广告包

时间:2014-06-02 21:43:03

标签: android bluetooth-lowenergy

我正在研究广告制造商特定数据的BLE传感器。是否有任何示例代码演示如何在Android中接收广告数据包并解析其有效负载?

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:18)

这就是我想要的:

BLE扫描API BluetoothAdapter.startLeScan(ScanCallback)需要回扫功能才能获得扫描结果。该方法需要如下所示:

    private BluetoothAdapter.LeScanCallback ScanCallback =
        new BluetoothAdapter.LeScanCallback()onLeScan(final BluetoothDevice device, 
                                                            int rssi, 
                                                      final byte[] scanRecord)
    {...}

scanRecord变量是一个包含广告数据包有效负载的字节数组。

根据BLE规范,有效载荷的结构非常简单,如下所示:

数据包的长度最多为47个字节,包括:

  • 1字节序言
  • 4字节访问地址
  • 2-39字节广告channelPDU
  • 3字节CRC

对于广告传播频道,访问地址始终为0x8E89BED6。

PDU又有自己的头(2个字节:有效载荷的大小及其类型 - 设备是否支持连接等)和实际有效载荷(最多37个字节)。

最后,有效载荷的前6个字节是设备的MAC地址,实际信息最多可以有31个字节。

实际信息的格式如下:

第一个字节是数据的长度,第二个字节是类型,后跟数据。

如果他们不关心内容,这是一种允许任何应用程序跳过整个数据记录的聪明方法。

以下是确定广告数据包内容的示例代码:

parseAdvertisementPacket(final byte[] scanRecord) {

    byte[] advertisedData = Arrays.copyOf(scanRecord, scanRecord.length);

    int offset = 0;
    while (offset < (advertisedData.length - 2)) {
        int len = advertisedData[offset++];
        if (len == 0)
            break;

        int type = advertisedData[offset++];
        switch (type) {
            case 0x02: // Partial list of 16-bit UUIDs
            case 0x03: // Complete list of 16-bit UUIDs
                while (len > 1) {
                    int uuid16 = advertisedData[offset++] & 0xFF;
                    uuid16 |= (advertisedData[offset++] << 8);
                    len -= 2;
                    uuids.add(UUID.fromString(String.format(
                            "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
                }
                break;
            case 0x06:// Partial list of 128-bit UUIDs
            case 0x07:// Complete list of 128-bit UUIDs
                // Loop through the advertised 128-bit UUID's.
                while (len >= 16) {
                    try {
                        // Wrap the advertised bits and order them.
                        ByteBuffer buffer = ByteBuffer.wrap(advertisedData,
                                offset++, 16).order(ByteOrder.LITTLE_ENDIAN);
                        long mostSignificantBit = buffer.getLong();
                        long leastSignificantBit = buffer.getLong();
                        uuids.add(new UUID(leastSignificantBit,
                                mostSignificantBit));
                    } catch (IndexOutOfBoundsException e) {
                        // Defensive programming.
                        Log.e("BlueToothDeviceFilter.parseUUID", e.toString());
                        continue;
                    } finally {
                        // Move the offset to read the next uuid.
                        offset += 15;
                        len -= 16;
                    }
                }
                break;
            case 0xFF:  // Manufacturer Specific Data
                Log.d(TAG, "Manufacturer Specific Data size:" + len +" bytes" );
                while (len > 1) {
                    if(i < 32) {
                        MfgData[i++] = advertisedData[offset++];
                    }
                    len -= 1;
                }
                Log.d(TAG, "Manufacturer Specific Data saved." + MfgData.toString());
                break;
            default:
                offset += (len - 1);
                break;
        }
    }

感谢

how-ibeacons-work

bluetooth org specs

mass让我朝着正确的方向前进!

答案 1 :(得分:3)

ADPayloadParser中的

nv-bluetooth解析广告包的有效负载并返回AD结构列表。 AD结构格式在&#34; 11 ADVERTISING AND SCAN RESPONSE DATA FORMAT&#34; &#34;蓝牙核心规范4.2&#34;。

以下代码段是onLeScan方法的实现示例。

public void onLeScan(
    BluetoothDevice device, int rssi, byte[] scanRecord)
{
    // Parse the payload of the advertising packet.
    List<ADStructure> structures =
        ADPayloadParser.getInstance().parse(scanRecord);

    // For each AD structure contained in the advertising packet.
    for (ADStructure structure : structures)
    {
        if (structure instanceof IBeacon)
        {
            // iBeacon packet was found.
            handleIBeacon((IBeacon)structure);
        }
        ......
    }
}

您可以将自己的解析器注册为ADPayloadParser,以获取特定于制造商的格式。有关详细信息,请参阅以下链接。

博客:http://darutk-oboegaki.blogspot.jp/2015/03/ibeacon-as-kind-of-ad-structures.html

GitHub:https://github.com/TakahikoKawasaki/nv-bluetooth

JavaDoc:http://takahikokawasaki.github.io/nv-bluetooth/

Maven:http://search.maven.org/#search|ga|1|a%3A%22nv-bluetooth%22

答案 2 :(得分:0)

编辑21.02.2016

我在下面链接的图书馆似乎已被移动; 见https://github.com/AltBeacon/android-beacon-library


您可以使用Android iBeacon Library开始。

有一个参考应用程序,您可以将其用于基础知识和模拟数据。 〜https://github.com/RadiusNetworks/ibeacon-reference-android~

一旦启动并运行,您可能希望导入库并将其与您的真实设备一起使用,网站上还有一些示例代码: http://developer.radiusnetworks.com/ibeacon/android/samples.html