蓝牙ble 广播包解析

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;
            }
        }
    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值