繁体   English   中英

在Android中读取广告包

[英]Read advertisement packet in Android

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

这就是我要找的:

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 个字节)。

最后,payload的前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;
        }
    }

谢谢

信标如何工作

蓝牙组织规格

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

nv-bluetooth 中的ADPayloadParser解析广告数据包的负载并返回 AD 结构列表。 AD结构格式在“Bluetooth Core Specification 4.2”的“11 ADVERTISING AND SCAN RESPONSE DATA FORMAT”中有描述。

以下代码片段是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

编辑 21.02.2016

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


您可以先使用 Android iBeacon 库。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM