在Android中获取蓝牙低功耗RSP扫描

问题描述 投票:0回答:3

我正在开发一个半标准的ibeacon,需要使用RSP广播领域,我正在使用TI CC2541广播Adv和RSP,工作正常从TI Packet Sniffer结果附加。

我没有在我的Samsung Note3,Android 4.4.2上使用http://developer.android.com/guide/topics/connectivity/bluetooth-le.html的示例获得RSP测试数据{0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}扫描,我添加的Log.d代码是:

// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mLeDeviceListAdapter.addDevice(device);
                mLeDeviceListAdapter.notifyDataSetChanged();
            }
        });

       Log.d("Tag101: ", device.getAddress() + "||"+Integer.toString(rssi) + "||"+toHexadecimal(scanRecord));
    }
};

结果:

10-15 21:07:28.066 19840-19853 / com.example.android.bluetoothlegatt D / Tag101 :: 20:CD:39:B1:52:C2 || -52 || 02 01 06 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 01 00 02 cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10-15 21:07:28.286 19840-19840 / com.example.android.bluetoothlegatt D / dalvikvm:GC_FOR_ALLOC释放514K,13%免费10104K / 11604K,暂停15ms,总计15ms 10-15 21:07:28.571 19840-19852 / com.example.android.bluetoothlegatt D / BluetoothAdapter:onScanResult() - Device = 20:CD:39:B1:52:C2 RSSI = -52 10-15 21:07:28.571 19840-19852 / com。 example.android.bluetoothlegatt D / Tag101 :: 20:CD:39:B1:52:C2 || -52 || 02 01 06 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 01 00 02 cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10-15 21:07:29.081 19840-2874 /com.example.android.bluetoothlegatt D / BluetoothAdapter:onScanResult() - Device = 20:CD:39:B1:52:C2 RSSI = - 51 10-15 21:07:29.081 19840-2874 / com.example.android.bluetoothlegatt D / Tag101 :: 20:CD:39:B1:52:C2 || -51 || 02 01 06 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 01 00 02 cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10-15 21:07:29.581 19840-2873 / com.example.android.bluetoothlegatt D / BluetoothAdapter:onScanResult() - Device = 20:CD:39:B1:52:C2 RSSI = -51

TI Packet Sniffer可以正确扫描测试数据:enter image description here

任何人都可以建议如何在Android代码中获得RSP,我是否需要初始扫描请求?一些示例代码会很棒。谢谢。

android bluetooth-lowenergy ibeacon-android
3个回答
0
投票

Android通常会自行请求扫描响应,并且在收到时,它会将scanRecord附加到PDU以进行扫描响应。我看到您显示的扫描记录输出中没有发生这种情况。

您可以尝试传输可连接的广告,看看这是否有所不同。 Android可能仅请求和处理可连接广告的扫描响应。


0
投票

尝试使用此Kotlin类来解析RSA数据,也可以将其转换为Java

最后你会得到一个包含所有必要RSA数据的Map数组

enum class EBLE {

    EBLE_ZERO, // Zero element
    EBLE_FLAGS, //«Flags»   Bluetooth Core Specification:
    EBLE_16BitUUIDInc, //«Incomplete List of 16-bit Service Class UUIDs»    Bluetooth Core Specification:
    EBLE_16BitUUIDCom, //«Complete List of 16-bit Service Class UUIDs»  Bluetooth Core Specification:
    EBLE_32BitUUIDInc,//«Incomplete List of 32-bit Service Class UUIDs» Bluetooth Core Specification:
    EBLE_32BitUUIDCom,//«Complete List of 32-bit Service Class UUIDs»   Bluetooth Core Specification:
    EBLE_128BitUUIDInc,//«Incomplete List of 128-bit Service Class UUIDs»   Bluetooth Core Specification:
    EBLE_128BitUUIDCom,//«Complete List of 128-bit Service Class UUIDs» Bluetooth Core Specification:
    EBLE_SHORTNAME,//«Shortened Local Name» Bluetooth Core Specification:
    EBLE_LOCALNAME,//«Complete Local Name»  Bluetooth Core Specification:
    EBLE_TXPOWERLEVEL,//«Tx Power Level»    Bluetooth Core Specification:
    EBLE_DEVICECLASS,//«Class of Device»    Bluetooth Core Specification:
    EBLE_SIMPLEPAIRHASH,//«Simple Pairing Hash C»   Bluetooth Core Specification:​«Simple Pairing Hash C-192»   ​Core Specification Supplement, Part A, section 1.6
    EBLE_SIMPLEPAIRRAND,//«Simple Pairing Randomizer R» Bluetooth Core Specification:​«Simple Pairing Randomizer R-192» ​Core Specification Supplement, Part A, section 1.6
    EBLE_DEVICEID,//«Device ID» Device ID Profile v1.3 or later,«Security Manager TK Value» Bluetooth Core Specification:
    EBLE_SECURITYMANAGER,//«Security Manager Out of Band Flags» Bluetooth Core Specification:
    EBLE_SLAVEINTERVALRA,//«Slave Connection Interval Range»    Bluetooth Core Specification:
    EBLE_16BitSSUUID,//«List of 16-bit Service Solicitation UUIDs»  Bluetooth Core Specification:
    EBLE_128BitSSUUID, //«List of 128-bit Service Solicitation UUIDs»   Bluetooth Core Specification:
    EBLE_SERVICEDATA,//«Service Data»   Bluetooth Core Specification:​«Service Data - 16-bit UUID»  ​Core Specification Supplement, Part A, section 1.11
    EBLE_PTADDRESS,//«Public Target Address»    Bluetooth Core Specification:
    EBLE_RTADDRESS,//«Random Target Address»    Bluetooth Core Specification:
    EBLE_APPEARANCE,//«Appearance»  Bluetooth Core Specification:
    EBLE_DEVADDRESS,//«​LE Bluetooth Device Address»    ​Core Specification Supplement, Part A, section 1.16
    EBLE_LEROLE,//«​LE Role»    ​Core Specification Supplement, Part A, section 1.17
    EBLE_PAIRINGHASH,//«​Simple Pairing Hash C-256» ​Core Specification Supplement, Part A, section 1.6
    EBLE_PAIRINGRAND,//«​Simple Pairing Randomizer R-256»   ​Core Specification Supplement, Part A, section 1.6
    EBLE_32BitSSUUID,//​«List of 32-bit Service Solicitation UUIDs» ​Core Specification Supplement, Part A, section 1.10
    EBLE_32BitSERDATA,//​«Service Data - 32-bit UUID»   ​Core Specification Supplement, Part A, section 1.11
    EBLE_128BitSERDATA,//​«Service Data - 128-bit UUID» ​Core Specification Supplement, Part A, section 1.11
    EBLE_SECCONCONF,//​«​LE Secure Connections Confirmation Value»  ​Core Specification Supplement Part A, Section 1.6
    EBLE_SECCONRAND,//​​«​LE Secure Connections Random Value»   ​Core Specification Supplement Part A, Section 1.6​
    EBLE_3DINFDATA, //​​«3D Information Data»   ​3D Synchronization Profile, v1.0 or later
    EBLE_MANDATA; //«Manufacturer Specific Data»    Bluetooth Core Specification:

    companion object {
        private val map = EBLE.values()
        fun fromInt(type: Int) = if (type > 0) map[type] else EBLE_MANDATA

        fun getDistance(rssi: Int, txPower: Int) = {
            /*
             * RSSI = TxPower - 10 * n * lg(d)
             * n = 2 (in free space)
             *
             * d = 10 ^ ((TxPower - RSSI) / (10 * n))
            */

            Math.pow(10.0, (txPower.toDouble() - rssi) / (10 * 2))
        }

      /*
     BLE Scan record parsing
    */
    fun parseRecord(scanRecord: ByteArray): Map<EBLE, ByteArray> {
        val ret = HashMap<EBLE, ByteArray>()
        var index = 0
        while (index < scanRecord.size) {
            val length = scanRecord[index++].toInt()
            //Zero value indicates that we are done with the record now
            if (length == 0) break

            val type = scanRecord[index].toInt()
            //if the type is zero, then we are pass the significant section of the data,
            // and we are thud done
            if (type == 0) break

            Arrays.copyOfRange(scanRecord, index + 1, index + length)?.let {
                ret[EBLE.fromInt(type)] = it //HexUtil.formatHexString(it)
            }

            index += length
        }

        return ret
    }

    fun getServiceUUID(record: Map<EBLE, ByteArray>): String {
        return when {
            record.containsKey(EBLE.EBLE_128BitUUIDCom) -> {
                val tmpString = HexUtil.formatHexString(record[EBLE.EBLE_128BitUUIDCom]?.reversedArray())
                tmpString.substring(0, 8) + "-" + tmpString.substring(8, 12) + "-" + tmpString.substring(12, 16) + "-" + tmpString.substring(16, 20) + "-" + tmpString.substring(20, tmpString.length)
            }
            record.containsKey(EBLE.EBLE_32BitUUIDCom) -> {
                HexUtil.formatHexString(record[EBLE.EBLE_32BitUUIDCom]?.reversedArray()) + "-0000-1000-8000-00805f9b34fb"
            }
            record.containsKey(EBLE.EBLE_128BitUUIDInc) -> { // Todo: Remove after bugfix !!!
                val tmpString = HexUtil.formatHexString(record[EBLE.EBLE_128BitUUIDInc]?.reversedArray())
                tmpString.substring(0, 8) + "-" + tmpString.substring(8, 12) + "-" + tmpString.substring(12, 16) + "-" + tmpString.substring(16, 20) + "-" + tmpString.substring(20, tmpString.length)
            }
            else -> {
                "undefined"
            }
        }
    }

    fun getServiceUUID(scanRecord: ByteArray): String {
        return getServiceUUID(parseRecord(scanRecord))
    }

}

Gist link


0
投票

我已经解决了这个问题,我需要指定scan_RSP的长度:

// GAP - SCAN RSP data (max size = 31 bytes)
{ 
  0x05, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE
};

Log.d结果:

设备= 20:CD:39:B1:52:C2 RSSI = -47 10-15 23:20:29.416 4780-4792 / com.example.android.bluetoothlegatt D / Tag101 :: 20:CD:39:B1:52 :C2 || -47 || 02 01 06 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 01 00 02 cd 05 aa bb cc dd ee 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10-15 23:20:29.921 4780-4791 / com.example.android.bluetoothlegatt D / BluetoothAdapter:onScanResult() - Device = 20 :CD:39:B1:52:C2 RSSI = -47 10-15 23:20:29.921 4780-4791 / com.example.android.bluetoothlegatt D / Tag101 :: 20:CD:39:B1:52:C2 | | -47 || 02 01 06 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 01 00 02 cd 05 aa bb cc dd ee 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

© www.soinside.com 2019 - 2024. All rights reserved.