欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝牙ble 广播包解析

程序员文章站 2024-03-24 23:18:52
...

AD type定义

摘录于:https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile

借鉴与:http://blog.csdn.net/h_o_w_e/article/details/50628568

注意:该解析适合标准蓝牙广播,有的破坏者为了让别人解析不出来会对广播包数据打乱,需要还原真实广播后才能解析。

撸起袖子开始搬

/**
     * 解析ble广播
     * 1、蓝牙广播长度62  前31定义位广播数据 后31位响应数据
     * 2、有效数据部分 :包含若干个广播数据单元,称为 AD Structure,每个单元可能存放电量,厂商名,蓝牙名,server id 和数据 ,根据数据部分第一个字节确定类型。
     * 3、无效数据部分 :因为广播包的长度必须是 31 个 byte,如果有效数据部分不到 31 自己,剩下的就用 0 补全。
     * 4、AD Structure 的组成是:长度(第一个字节)+ 数据(数据部分第一个字节表示数据类型)
     * 5、数据类型定义:https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
     * 6、ble 广播单元解析例子:
     02 01   00 // 长度:2   类型: 01       数据 :00
     10 ff   63 00  0b  0b  0b  0b  0b  0b  0b  0b  0b  0b  0b  0b  0b  
     //10为长度    ff类型即厂商 63...0b为真实数据
     06 16  f4   18 01   02 03      //server uuid 携带参数
     0a 09  42  6c  65  53  65  72  76  65  72      //蓝牙完整名称ascll码对照
     02 0a  eb                       //电量
     03 02  f4  18                  //16位server uuid
     00 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  //补位
    多个广播单元组成ble广播
     * @param adv_data      62bite广播
     * @return  Map
     */
    public Map<String, String> parseData(byte[] adv_data) {
        ByteBuffer buffer = ByteBuffer.wrap(adv_data).order(ByteOrder.LITTLE_ENDIAN);    //创建缓冲byte,一个个取出

        Map<String, String> map = new HashMap<>(); //存放数据单元的map
        while (true) {       //每次读一个单元
            byte length = buffer.get();      //获取缓冲数据中的当前即第一个数即数据部分的长度
            if (length == 0){return map;}   //长度为0即没有数据 返回map退出循环
            byte type = buffer.get();      //广播单元:长度+数据len, 数据第一个数为类型  真实数据部分len-1
            Log.i(TAG, toHexString(type)); //toHexString(byte) 是Integer.toHex..将16的byte转字符串
            length -= 1;                   //去掉第一个数(类型)才是真实数据   
            byte[] data = new byte[length];//存放真实数据的数组
            buffer.get(data, 0, length);  //取真实数据存放与data
            switch (type) {
                case 0x01: // Flags
                    map.put("flag", toHexString(data));
                    break;
                case 0x02: // Partial list of 16-bit UUIDs
                case 0x03: // Complete list of 16-bit UUIDs
                case 0x14: // List of 16-bit Service Solicitation UUIDs
                    map.put("uuid_16", toHexString(data));
                    break;
                case 0x08: // Short local device name
                case 0x09: // Complete local device name
                    map.put("localName", toHexString(data));   //解出来的数对应ascll码
                    break;
                case (byte) 0xFF: // Manufacturer Specific Data
                    map.put("Manufacturer", toHexString(data));
                    break;
                default: // skip
                    break;
            }
        }
    }