玩转BLE(3)_使用微信蓝牙精简协议伪造记步数据
作者:wowo 发布于:2017-3-11 11:42 分类:蓝牙
1. 前言
在物联网时代,有一个问题肯定会让人头疼(现在已经初露端倪了):
物联网中的IOT设备有两个主要特点:
1)简单小巧(不具备复杂的人机交互接口,需要手机等终端设备辅助完成配置、控制等功能)。
2)数量和种类繁多(消费者面对的可是数量众多的不同厂家、不同类型的设备)。基于这两个特点,手机等终端设备一般通过APP(或APK)对IOT设备进行控制,不同厂家的不同设备,通常需要不同的APP/APK。于是出现了这样的结果:
如果你家里有一个小米yeelight的床头灯,你需要安装一个yeelight的APP/APK;
如果你手上戴一个百度智能手环,你需要安装一个百度智能手环APP/APK;
如果你跑步时戴一个xxx运动蓝牙耳机,你需要安装一个xxx运动蓝牙耳机APP/APK;
如果你要骑摩拜单车,你需要安装一个摩拜单车APP/APK;
如果你也行骑一下优拜单车,你需要安装一个优拜单车APP/APK;
……(要列的话,我觉得永远都列不完,大家可以想象一下,这是不是一个灾难??)
既然有问题,肯定就有人试图解决,于是微信IoT、阿里小智、亚马逊IoT等等,互联网大佬们就各显神通了。最终谁能称霸天下,现在还不得而知,本文也不去讨论这些。
作为蓝牙BLE的介绍文章,本文将以微信IoT的“微信蓝牙精简协议”为例,通过“把一个蓝牙适配器模拟成微信计步器”,分别从BLE技术(怎样注册一个GATT service)和微信IoT(微信物联网平台的思路和想法)两个角度,窥一窥IoT江湖的冰山一角(权当开阔眼界了)。
2. 微信蓝牙精简协议简介
微信蓝牙精简协议的思路很简单(具体可参考“http://iot.weixin.qq.com/wiki/new/index.html?page=4-3“),如下图:
图片1 微信蓝牙精简协议框架
总结来说,就是:
通过微信(可以运行在手机、平板、电脑、等硬件上面)统一和IoT设备交互;
交互的介质是BLE协议(可以摇身变为其它无线协议);
交互的过程可由服务器协助完成(服务器可选择微信服务器或者第三方服务器)。
虽然思路简单,背后却有深深的“不怀好意”,因为:
1)IoT设备想要和微信(或者微信背后的服务器)交互,就必须遵守微信定义的协议;
2)IoT设备通过微信和服务的交互(无论是第三方服务器,还是微信服务器),都必须遵守微信定义的协议,并经由微信服务器转发。
基于上面两点,物联网中最重要的两个环节:设备和数据,都掌握在微信的手中了。恐怖!!
到目前为止,“微信蓝牙精简协议”有一个比较成熟的应用实例:微信计步器,其工作流程为:
1)在带有计步功能的BLE设备上,按照协议规定的方式,基于BLE GATT,实现相应的Profile、Service、Attribute。
2)在微信公众平台,为该设备申请一个唯一的设备ID,并和设备的MAC地址一起,在公众平台上注册、授权。
3)在微信的微信运动小程序中,扫描并添加该设备,即可通过BLE读取设备的计步信息。
4)微信运动读取计步信息后,可以进行后续的动作(例如在朋友圈刷排名等)。
以上步骤,后面章节将会使用一个蓝牙适配器(模拟蓝牙计步器),配合自己的手机微信,进行演示说明。
3. 将蓝牙适配器模拟成一个计步器
3.1 环境准备
后续实验基于如下的硬件、软件环境(其它环境也okay,不过我没有测试)。
运行Ubuntu为例的PC、笔记本(或者开发板),包含蓝牙4.0(及以上)功能(自带或者使用蓝牙适配器);
Ubuntu中安装有较新版本的Bluez协议栈及工具集,以及其它必须的软禁包(具体步骤略,碰到问题的时候可以一点点解决);
具有BLE功能的手机(上面有可以正常使用的微信);
3.2 搭建Golang开发环境
在包含Bluez(及相关工具集)的Linux OS中,使用Bluez的工具,可以完成大部分的BLE实验,例如:
hcitool、bluetoothctl等工具,可以进行BLE设备的扫描、连接、配对、广播等操作;
hcitool可以发送HCI command,设置BLE的广播数据;
gatttool可以在GATT层面,完成GATT profile的连接、service attribute的读写等操作;
等等。
但有一个功能点,不是很容易实现,就是如何自定义一个GATT profile(要知道,BLE 90%以上的功能都是通过GATT实现的,如果做到这一点,学习BLE就非常方便了)。当然,BLE不复杂,我们可以直接使用BLuez提供的API,自行开发。如果是产品开发,无可厚非,但是如果仅仅只做个实验,这样大张旗鼓的就不划算了,最好能有一些开源的工具。确实有,我搜集、尝试过几种工具:
1)使用bluez的测试代码(bluez-5.37/test/example-gatt-server),是一个python脚本。这个家伙对环境依赖度比较高,很难用,最终没有用起来。
2)一个由nodejs脚本写的工具(https://github.com/luluxie/weixin-iot)。基本功能还好,不过本人对js不太熟,就算了。
3)一个由Go语言写的工具(https://github.com/paypal/gatt)。功能OK,关键还是新奇的Go语言,果断使用~~
这就是搭建Golang开发环境的原因。至于步骤,很简单(以Ubuntu为例):
1)安装Go语言
sudo apt install golang2)创建GOPATH环境变量
mkdir ~/gopath
export GOPATH=$HOME/gopath #为了方便,可以放到~/.profile中
3.3 代码准备
在github上,从https://github.com/paypal/gatt中clone一个仓库,clone的仓库地址为https://github.com/wowotech/gatt。clone后使用go get命令,下载代码到本地:
vim@ubuntu:~$ go get github.com/wowotech/gatt
下载后代码的位置为:
vim@ubuntu:~$ ls $GOPATH/src/github.com/wowotech/
gatt
然后,手动将代码中所有的“github.com/paypal”类型的import修改为“github.com/wowotech”(fuck Go!!)
cd $GOPATH/src/github.com/wowotech/gatt
find . -name "*.go" | xargs sed -i 's/paypal/wowotech/g'
提交记录如下:
https://github.com/wowotech/gatt/commit/1f1c23e94cb7e1b54078a568a60cf1aaef7de195
3.4 编译并运行一个示例文件.
(略)。
3.5 支持“微信蓝牙精简协议”
参考examples/server.go以及蓝牙精简协议的定义[1],新建weixin.go,增加微信蓝牙精简协议。最终的文件如下(代码很简单,熟悉BLE GATT协议的同学,很容易看懂,就不过多解释了):
https://github.com/wowotech/gatt/commit/942e7480ad1664dabacdb5561fa98a831621f7de
注1:可以通过代码中如下的定义修改计步的步数(想刷爆微信运动朋友圈的同学注意了,嘿嘿!!):
+ // steps little endian
+ // 01(steps) 10 27 00(0x002710 = 10000)
+ // http://iot.weixin.qq.com/wiki/new/index.html?page=4-3
+ steps := []byte{ 0x01, 0x5c, 0x74, 0x01 }
3.6 编译、运行、测试
编译:
vim@ubuntu:~/gopath/src/github.com/wowotech/gatt/examples$ go build weixin.go
运行:
vim@ubuntu:~/gopath/src/github.com/wowotech/gatt/examples$ sudo ./weixin
[sudo] password for vim:
2017/03/04 01:03:13 dev: hci0 up
2017/03/04 01:03:14 dev: hci0 down
2017/03/04 01:03:14 dev: hci0 opened
State: PoweredOn
2017/03/04 01:03:14 BD Addr: 5C:F3:70:6A:BA:27
2017/03/04 01:03:14 Generating attribute table:
2017/03/04 01:03:14 handle type props secure pvt value
2017/03/04 01:03:14 0x0001 0x2800 0x02 0x00 *gatt.Service [ E7 FE ]
2017/03/04 01:03:14 0x0002 0x2803 0x32 0x00 *gatt.Characteristic [ 32 03 00 A1 FE ]
2017/03/04 01:03:14 0x0003 0xfea1 0x32 0x00 *gatt.Characteristic [ ]
2017/03/04 01:03:14 0x0004 0x2902 0x0E 0x00 *gatt.Descriptor [ 00 00 ]
2017/03/04 01:03:14 0x0005 0x2803 0x3E 0x00 *gatt.Characteristic [ 3E 06 00 A2 FE ]
2017/03/04 01:03:14 0x0006 0xfea2 0x3E 0x00 *gatt.Characteristic [ ]
2017/03/04 01:03:14 0x0007 0x2902 0x0E 0x00 *gatt.Descriptor [ 00 00 ]
2017/03/04 01:03:14 0x0008 0x2803 0x02 0x00 *gatt.Characteristic [ 02 09 00 C9 FE ]
2017/03/04 01:03:14 0x0009 0xfec9 0x02 0x00 *gatt.Characteristic [ ]
然后在手机下载AirSyncDebugger2.3.0.apk(http://iot.weixin.qq.com/wiki/new/index.html?page=4-3的底部)测试精简协议是否okay:
打开APK---->精简协议---->计步器测试
测试界面如下(Android平台):
4. 在微信公众平台注册并授权设备
第2章成功模拟出来一个遵守“微信蓝牙精简协议”的计步器之后,我们需要登录微信的公众平台(可以使用测试帐号),注册一个产品类别,并授权该设备,之后就可以在微信运动界面使用这个设备了。
4.1 登录“微信公众平台接口测试帐号”
打开下面链接:
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
点击登录按钮,用自己微信的扫一扫登录,登录后的界面如下:
注意图中红色涂抹的三个信息(要记录下来,后面有用):
微信号:
appID:
appsecret:
4.2 开启设备功能接口
将上面的登录界面往下拉,找到“功能服务”,“设备功能”,点击“开启”,开启设备功能接口,如下图:
4.3 添加产品
设备功能接口开启后,会出现“设置”按钮,点击进入下一个界面,进行设备功能管理。在该界面,点击“添加产品”按钮,为我们的计步器设备添加一个产品类别:
按照提示填入相关的信息(需要注意红色圈出的地方):
点击“下一步”进入“产品能力登记”界面:
最后,点击“添加”按钮,将产品添加进去。添加成功后,进入如下的界面(注意其中红色涂抹的那一串数字,是产品的ID,记下来,后面有用):
4.4 授权设备
4.4.1 获取access_token
根据上面得到的appID和appsecret,在浏览器里面输入如下指令,获取访问微信公众平台的token(令牌):
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxxxxxxxxx&secret=xxxxxxxx
注意红色部分要修改为实际内容(具体可参考4.1章节获取的信息)。
浏览器会返回如下内容:
{"access_token":"xxxxxxxxxxxxxxxxxxx","expires_in":7200}
有两个字段,access_token(记录下来,后面有用)和有效时间(7200秒,很长了)。
4.4.2 为设备生成一个唯一ID(device_id)及二维码(通过微信扫描即可添加设备)
在浏览器输入如下指令:
https://api.weixin.qq.com/device/getqrcode?access_token=xxxxxxxxxxxx&product_id=xxxxx
其中access_token为4.4.1中获取的,product_id为4.3中获取的。
浏览器的返回如下:
{"base_resp":{"errcode":0,"errmsg":"ok"},"deviceid":"xxxxxx","qrticket":"http:\/\/we.qq.com\/d\/AQArGYez06UDOcqKNe1jqWeeLhiF7fIKebEP5hiT"}
deviceid为新生成的唯一ID,记录下来,后面有用。
qrticket是设备的二维码,随便找一个二维码生成的网站(例如http://cli.im/),就可得到图片二维码,如下(注意需要将浏览器返回的转义字符改回正常):
4.4.3 设备鉴权
这一步要借助微信公众平台的debug页面了,单纯的浏览器无法搞定。打开如下的debug地址:
找到如下界面:
body输入的内容如下:
{
"device_num":"1",
"device_list":[
{
"id":" xxxxxxxx",
"mac":"5CF3706ABA27",
"connect_protocol":"3",
"auth_key":"",
"close_strategy":"1",
"conn_strategy":"5",
"crypt_method":"0",
"auth_ver":"0",
"manu_mac_pos":"-1",
"ser_mac_pos":"-2",
"ble_simple_protocol": "1"
}
],
"op_type":"0",
"product_id": "xxxxx"
}
注意上面红色的字段,id是4.4.2中获得的deviceid,mac是蓝牙设备的物理地址,product_id是4.3中获得产品ID的。
点击“检查问题”,看到如下的成功信息,说明授权成功了:
5. 使用手机微信绑定设备
使用微信扫一扫,扫描刚才获得的二维码,点击“绑定设备”,即可添加设备,如下:
绑定成功后,设备显示未连接,如下:
接下来要连接设备。对iOS来说,在设置界面无法主动连接BLE设备,必须有应用程序自行连接,这里以微信运动为例,搜索并连接刚才授权的那个设备,即可看到计步数据的更新。步骤如下面图片(不再解释了,大家可以自己试试):
6. 参考文档
[1] 微信蓝牙精简协议,http://iot.weixin.qq.com/wiki/new/index.html?page=4-3
[2] https://github.com/paypal/gatt
原创文章,转发请注明出处。蜗窝科技,www.wowotech.net。
标签: 蓝牙 Bluetooth BLE golang 微信 airsync iot

评论:
2017-12-14 15:29
我使用 bluez-5.47 在一个raspberry3b上.然后我想用我的Android 手机连接这个ble.我在我的raspberry 3b上面使用了 blue-5.47/test/example-gatt-server .可是 我使用google play的ble测试应用."ble scanner" 看不到 example-gatt-server 创建的服务.但是我使用我同事的iphone手机可以连接.可以看到服务.
窝窝.有空帮我看看 ... ... 万分感谢.好人一生平安
测试手机 iphone 6,8
小米4 6 max2
2017-10-27 14:37
2017-06-19 10:48
我的环境是 ubuntu 12.04 ,bluez 5.37 ,go 1.8.3
按照步骤编译完成 执行 sudo ./weixin 却提示,按说笔记本蓝牙适配器是dell 1705 bluetooth,应该支持bluetooth 4.0,旧版本的bluez也被我purge后重新编译安装了,不知道还有什么需要升级还是有啥其他的问题 - -:
2017/06/19 10:32:11 dev: hci0 does not support LE
2017/06/19 10:32:11 Failed to open device, err: no supported devices available
执行 hciconfig -a:
hci0: Type: BR/EDR Bus: USB
BD Address: 9C:D2:1E:7A:8A:6C ACL MTU: 8192:128 SCO MTU: 64:128
UP RUNNING
RX bytes:5318 acl:0 sco:0 events:97 errors:0
TX bytes:364 acl:0 sco:0 commands:56 errors:0
Features: 0xff 0xff 0x8f 0xfe 0x83 0xe1 0x08 0x80
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT
Name: 'Virtual Bluetooth Adapter'
Class: 0x000100
Service Classes: Unspecified
Device Class: Computer, Uncategorized
HCI Version: 2.1 (0x4) Revision: 0x100
LMP Version: 2.1 (0x4) Subversion: 0x100
Manufacturer: not assigned (6502)
我是小白,还望 wowo 有空可以指点一下,谢谢啦
2017-03-14 16:34
result=false,Has no 0xfee7 or standard service in broadcast record!
广播包:02 01 06 0D FF 00 0A 12 34 56 78 9A BC 03 03 E7 FE 0A 09 4D 42 31 32 2D 31 32 33 34 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 00
2017-03-14 16:54
http://www.wowotech.net/bluetooth/ble_broadcast.html
http://iot.weixin.qq.com/wiki/new/index.html?page=4-3
https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
02 01 06(OK)
Data的长度是02;Data是01 06;AD Type是01(Flags);AD Data是06,表明支持General Discoverable Mode、不支持BR/EDR。
0D FF 00 0A 12 34 56 78 9A BC 03 03 E7 FE(0D这个长度有问题!!)
Data的长度是0D,Data是FF 00 0A 12 34 56 78 9A BC 03 03 E7 FE;
AD Type是FF(厂商自定义),AD Data是00 0A 12 34 56 78 9A BC 03 03 E7 FE;(参考http://iot.weixin.qq.com/wiki/new/index.html?page=4-3)
00 0A:厂商ID
12 34 56 78 9A BC:MAC地址
03 03 E7 FE(service信息,但是service的长度包在0D这个长度里面了)。
0A 09 4D 42 31 32 2D 31 32 33 34(OK)
Data的长度是0A,Data是09 4D 42 31 32 2D 31 32 33 34;
AD Type是09(Complete Local Name),AD Data是4D 42 31 32 2D 31 32 33 34(MB12-1234)
功能
最新评论
- bngvfzkblj
大话西游丝路传说一条龙www.81uv.com9155155... - bngvmdwirj
征途永恒之塔一条龙www.a3sf.com776356990... - luc
keventd_wq 从2010 年就变成 system_w... - linux-fan
一、前言 1、推迟到top half执行完毕 ->... - 内核菜鸟
感谢分享 - deven
@一个网友:从数据结构定义就能知道肯定不支持大页
文章分类
随机文章
文章存档
- 2024年2月(1)
- 2023年5月(1)
- 2022年10月(1)
- 2022年8月(1)
- 2022年6月(1)
- 2022年5月(1)
- 2022年4月(2)
- 2022年2月(2)
- 2021年12月(1)
- 2021年11月(5)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(3)
- 2020年3月(3)
- 2020年2月(2)
- 2020年1月(3)
- 2019年12月(3)
- 2019年5月(4)
- 2019年3月(1)
- 2019年1月(3)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(2)
- 2018年8月(1)
- 2018年6月(1)
- 2018年5月(1)
- 2018年4月(7)
- 2018年2月(4)
- 2018年1月(5)
- 2017年12月(2)
- 2017年11月(2)
- 2017年10月(1)
- 2017年9月(5)
- 2017年8月(4)
- 2017年7月(4)
- 2017年6月(3)
- 2017年5月(3)
- 2017年4月(1)
- 2017年3月(8)
- 2017年2月(6)
- 2017年1月(5)
- 2016年12月(6)
- 2016年11月(11)
- 2016年10月(9)
- 2016年9月(6)
- 2016年8月(9)
- 2016年7月(5)
- 2016年6月(8)
- 2016年5月(8)
- 2016年4月(7)
- 2016年3月(5)
- 2016年2月(5)
- 2016年1月(6)
- 2015年12月(6)
- 2015年11月(9)
- 2015年10月(9)
- 2015年9月(4)
- 2015年8月(3)
- 2015年7月(7)
- 2015年6月(3)
- 2015年5月(6)
- 2015年4月(9)
- 2015年3月(9)
- 2015年2月(6)
- 2015年1月(6)
- 2014年12月(17)
- 2014年11月(8)
- 2014年10月(9)
- 2014年9月(7)
- 2014年8月(12)
- 2014年7月(6)
- 2014年6月(6)
- 2014年5月(9)
- 2014年4月(9)
- 2014年3月(7)
- 2014年2月(3)
- 2014年1月(4)
2018-04-01 20:12