微信蓝牙接口协议是什么,如何在我的APP中使用

微信蓝牙BLE接入调试指引 测试公众号篇分享
微信蓝牙BLE接入调试指引
测试公众号篇
2微信测试公众号
2.1申请测试公众号
可以在http://mp./debug/cgi-bin/sandbox?t=sandbox/login申请到一个用于测试的公众号,这个帐号可以用于调试具用AirSync协议的蓝牙设备,简精协议好像调不了。
申请步骤:
打开网址,点击登陆后,出来二维码,用微信扫一下,在弹出的页面点确认登陆,然后网页会自动进入测试号界面
进入后,注意一下上图标红线的值,BLE固件里的DEVICE_TYPE的值要改成上面标红微信号的值,而appID和appsecret这两个值在获取access_token时会用到。
2.2添加蓝牙产品
在测试号界面,找到&功能服务&-》&设备功能&,点开启,然后进行设置,进去后添加产品,然后参考下图填写,就红圈要注意,其他随便填。
添加完后,并不表示进入公众号后就可以去连蓝牙了,这只是将公众号配置成具有蓝牙功能,想要连接蓝牙设备,还得继续往下。另外,注意上图标红圈的那个值6563,它是产品ID(product_id),在授权时会用到。
另外,说明一下,这里提到的产品是什么意思,要是以为是一个设备就是一样产品,那就惨了,因为测试帐号的限额就5个产品。我的理解是,一个产品,是指具有相同接口功能的硬件,比如蓝牙手表,就一个产品,所有手表都是同一个产品,蓝牙手环也是一样产品,WIFI功能的设备,就另一个产品,是一样大种类,或者叫做功能类别。
刚创建的这个产品,只是个空壳,接下来使用&微信公众平台接口调试工具&
来向产品添加蓝牙设备。
2.3添加蓝牙设备
打开,接口类型和接口列表按下图填写:
然后再一下appid和secret的值,appid是测试号界面的appID,secret是appsecret。填好后点一下&检查问题&,正常的话,会返回:
上面的请求地址,意思是,点击&检查问题&按钮时,实际执行的就是这个指令,你把这个地址拷到网页浏览,显示的信息就是返回结果。
access_token叫访问令牌,它的有效期是2小时,它的作用是下面提到的指令都得带访问令牌,否则测试号后台是不会接受的。
获取到access_token后,我们就可以添加设备了。将接口类型选择为&硬件接入API接口调试&,接口列表选择为&设备授权&:
在body里填入下面信息:
&device_num&:&1&,
&device_list&:[
&id&:&device3&,
&mac&:&f4e6f41549f2&,
&connect_protocol&:&3&,
&auth_key&:&b0c0d0e0f&,
&close_strategy&:&1&,
&conn_strategy&:&1&,
&crypt_method&:&1&,
&auth_ver&:&1&,
&manu_mac_pos&:&-1&,
&ser_mac_pos&:&-2&
&op_type&:&0&,
&product_id&:&6563&
正常返回如下:
我们来解读一下BODY的信息,BODY是一个json结构,即&变量&:&值&的格式构成,不清楚的可以查一下。
&device_num&:&1&,//表示device_list里有多少项,1表示1项,如果是2,list就得有两项。
&device_list&:[//设备列表
&id&:&device3&,//这个值要与BLE固件里的DEVICE_ID一致,可以自定义,也可通过微信HTTP接口生成。
&mac&:&f4e6f41549f2&,//这个值是硬件篇提到的BLE设备的MAC地址,与广播数据里的MAC地址顺序一样,也和手机扫描到的MAC地址顺序一样。
&connect_protocol&:&3&,//3表示BLE蓝牙协议
&auth_key&:&b0c0d0e0f&,//和BLE固件里的aes_key值一致。
&close_strategy&:&1&,//1:退出公众号页面时即断开连接
&conn_strategy&:&1&,//1:(第1bit置位)在公众号对话页面,不停的尝
试连接设备
&crypt_method&:&1&,//1:AES
&auth_ver&:&1&,//加密版本,0是不加密
&manu_mac_pos&:&-1&,//-1:MAC地址在尾部
&ser_mac_pos&:&-2&//-2:表示serialnumber不包含mac地址
&op_type&:&0&,//0表示新增,1表示更改,第一次用0,之后用1
&product_id&:&6563&//对用添加的产品号,op_type=0时需要。
设备授权,不表示进入微信号后就会连接设备,只是表示在后面的配置里可以被引用。
对上面的&id&项,详细说明一下,id指的是device_id,是唯一的,不能重名,它有两种产生方式,一种是用户自己定义,如上的device3就是我自己取的,另一种是调用微信接口产生:
一般在这里只填access_token,会产生错误提示:
&base_resp&:{
&errcode&:100020,
&errmsg&:&accountquotanotenough&
原因是deviceid的产生需要指定产品ID,表明它是基于哪个产品。解决方法是:在access_tokey里填写ACCESS_TOKEN&product_id=PRODUCT_ID,如下:
http的请求方式:
https://api./device/getqrcode?access_token=ue48NdvmlCrEcknhRP0FJwmeg0d0hOu9aB9Q9ZW0d6HB-RhM6O2ffnSxhzXvH8ClAgSJ1mYnHiQLRScXCH3tMfXv5X-Wlk5kYC6waMPCpyMIYKgAGAQGS&product_id=6563
正常返回结果:
会产生一个deviceid和一个二维码地址。这个二维码地址是对应该设备的,它与公众号二维码的不同是,它加入了设备信息,用户在扫描二维码后,可以绑定设备,而扫描公众号二维码,则不会要求绑定设备。
二维码地址可以通过这个网站http://cli.im/url来产生二维码图片。
另外,自己定义的deviceid,可以通过下命令来产生二维码地址:
curlhttps://api./device/create_qrcode?access_token=ACCESS_TOKEN-d&{\&device_num\&:\&1\&,\&device_id_list\&:[\&device3\&]}&
上面的access_token和device3要换成自己的。
Curl命令一般在linux终端下使用比较方便,WINDOWS的自己查一下。
2.4绑定设备
二维码图片产生后,在微信扫一扫,就会跳出绑定界面,已绑过的除外。
点击绑定后,微信就会将device3与用户的微号进行绑定,可以通调试接口工具,在&查询用户绑定的设备&中查到,
Openid是用户微信号,当用户微信关注设备后,可以在测试号界面里的用户列表上看到。
查询用户绑定的设备&也可通过下面命令查到:
https://api./device/get_bind_device?access_token=ACCESS_TOKEN&openid=微信号
这里的绑定,不是实际物理意义上的绑定,只是软件的配置,并没有形成实际的连接。在绑定后,进入公众号,公众号就才会根据它绑定的设备去扫描,当找到对应的设备后,才去连接。所以,如果没有配置好绑定信息,进入公众号后是不会去连接设备的。
另外,除了通过扫描设备二维码去绑定设备,还可以通过HTTP接口来绑定设备,这个可以参考下面2.6提到的强制绑定设备。
至此,绑定设备后就可以在公众号里连接BLE设备,完成第一阶段的握手,当然,数据的互发还得等第三方服务器建好后。
2.5设备接入接口协议
可以看到,调试工具的每个接口都有对应的http请求方式,这些请求方式,在《设备接入接口协议V2.3.2》里有详细解释,可以在http://iot./wiki/new/index.html?page=6-1下载。
接入接口协议有涉及第三方服务器接口,也有微信本身接口,下面做一下简单导读。
打开文档后,翻到目录,前缀是&消息接口&的,是微信发给第三方服务器的,方式是向地址http://URL?signature=SIGNATURE&tamp=&nonce=NONCE发送一段格式如下的xml数据:&& & &微信硬件平台使用蓝牙作为近场控制的连接件,并拟定了《微信蓝牙外设协议》。这份协议更像一个标准,用于规范微信和蓝牙外设之间的数据交互场景和接口。但从开发者来看,要完全读懂这份协议,恐怕需要熟读很多遍,并且要结合调试才能真正实现微信Airsync通信。笔者对IOT和微信硬件平台的整个框架和技术都比较熟悉了,并且已经在TI的CC254X和Dialog的DA14580上实现了微信Airsync协议通信。现在回过头来,从开发的角度,对微信Airsync协议进行重新解读,以帮助新进入物联网领域的开发者更快地掌握微信蓝牙设备通信开发,以让产品快速接入微信硬件平台。
&&&&&& 有关微信硬件平台和物联网的架构分析请参考笔者之前的博文,特别是《》和《》。
一、微信蓝牙物联的技术需求
  软件和协议都是需求驱动的。在物联网、移动互联网领域,理解场景是提炼需求的重要方法。那么,我们从场景分析的角度来理解微信硬件平台的蓝牙物联需求。
1.&&&& 微信蓝牙物联是一种近场控制场景
  微信硬件平台支持蓝牙和Wifi/3G/GPRS接入。Wifi/3G/GPRS是一种远场控制手段,只要网络可达,那么用户可以在远场(例如办公场所)控制离用户距离很远(例如家里)的物联设备。而蓝牙接入则是一种近场控制手段,用户只能利用微信通过手机的蓝牙来控制20米左右的蓝牙设备。也即是,当蓝牙设备离开手机蓝牙的连接范围,那么用户是控制不了该设备的。
对于蓝牙外设来说,手机就像一个蓝牙网关一样,手机通过蓝牙来跟蓝牙外设进行通信,将得到的数据通过手机的wifi或者3G/4G信号与云后端(微信公众平台、第三方云服务端)交互。前者是基于微信Airsync协议,后者则是微信制定的基于TCP/IP协议的《设备接入接口协议》。
2.&&&& 蓝牙外设身份注册
  微信硬件平台只提供两部分核心的物联功能,一是身份管理,二是消息推送。任何一个外设,不管是蓝牙还是wifi,它都将拥有一个唯一的设备ID。设备ID的相关描述请参考《》,其包括设备类型(设备厂商的公众号ID)和该设备厂商自行定义的设备ID。这种设计手段和蓝牙MAC地址、网卡MAC地址的设置是一样的。设备ID就是外设的身份。
在外设向微信硬件平台注册身份前,微信硬件平台是不认识这个外设的。所以,我们在使用蓝牙外设前,需要向微信硬件平台注册身份。
对于微信硬件平台而言,设备注册其实就是平台对这个设备进行授权(加入)的过程。接口如下图。其主要通过提交自身的唯一MAC、设备ID来向平台注册。
3.&&&& 蓝牙广播
  对于蓝牙设备来说,它主要的状态包括未连接和已连接两种状态。在未连接时,它需要进行广播。广播的目的是为了让手机微信能够通过蓝牙扫描得知这是一个支持蓝牙Airsync协议的设备。当手机微信识别到是一个支持该协议的外设时,手机微信会发起连接。
  那么,广播数据需要包含什么格式的数据才能被手机微信所识别到呢?这就是蓝牙Airsync协议规定的内容。
4.&&&& 蓝牙通信
  蓝牙连接之后,自然是数据通信的需求。对蓝牙BLE来说,数据通信都是通过访问某个characteristics来实现的。而characteristics需要支持以下场景:
  1)手机微信对外设进行写控制,要求characteristics的write属性。
  2)手机微信读取外设的一些信息。当外设和厂商自己研制的APP连上之后,外设处于连接状态,其不会再发出广播信息,此时微信想去连接这个外设怎么办?其是通过读取外设的信息,如MAC,来判断该外设是否支持微信。这要求characteristics的read属性。
  以上两种都是手机微信作为主动方,外设是被动。接下来,我们来看看外设是主动时的场景:
  3)例如,运动手环需要主动上报用户某个时段的运动步数。在这种情况下,手机微信主动读取运动步数显然是不合适的,因为手机不应该时时刻刻地读这个步数来更新。而应该是手机微信订阅characteristics的信息更新服务,即作为被动方接受外设的信息更新。
  对于蓝牙外设来说,characteristics的信息更新有两种,一种是notify,一种是indicate。他们有什么区别呢?对于notify,当蓝牙外设的characteristics的值有变化时,它会主动将新的值告知手机微信,而手机微信收到这个信息更新时不需要回复。而对于indicate属性,手机微信在收到这个信息时需要给蓝牙外设一个简单的回复。
  蓝牙BLE通信的characteristics的长度是有限制的,或者说每一帧数据长度是有限的,是20字节。那么,如果蓝牙外设有一串很长的数据要主动传送,很明显,它需要indicate属性才能完成这个任务,即将这段数据按20字节长度进行分帧,每次更新发送之后,需要等手机微信回复之后才能发下一个20字节,直到发完为止。
二、蓝牙微信Airsync协议开发
  根据以上对蓝牙微信物联的技术需求分析,再根据蓝牙BLE的应用开发知识,我们来梳理蓝牙微信Airsync协议的开发要点。
1.&&&& 广播
  蓝牙外设广播的目的是让手机微信能够识别到。微信Airsync协议是这样规定蓝牙外设广播数据格式的:
  1) 声明自己的ServiceUUID是0xFEE7。
  2) 在自定义厂商数据manufature specific data中需以MAC地址(身份注册时的MAC地址,也是该设备真实的MAC地址)结尾,并且要求manufature specific data的长度大于等于8.
  蓝牙的广播数据格式定义请参考《Blutoothspecification 4.0》的P1735页,对应以下两个类型:
  另外,微信Airsync协议提到广播设备分为两种,一种是普通设备,没有按钮,需要无时无刻地广播数据;另一种是确认设备,即有按钮,即用户按下按钮后才开始广播数据。事实上,现实生活中为了省功耗,不可能时时刻刻都在广播的,都是在用户拿手机过来后,再按下外设按钮之后才开始广播并连接的。但是微信把这种方式称为确认设备会造成困惑啊,又没解释清楚,以为广播之后还要确认什么的。这里明确解释这一点。
  对于确认按钮之后的广播数据需要注意的是,在自定义厂商数据manufature specific data中需以0xfe 0x01 0x01 +MAC地址结尾。
2.&&&& 蓝牙通信服务
  外设要实现以下特征,并根据具体芯片平台的接口实现各特征字的读写回调过程,以实现具体的应用需求。
  即写characteristics的UUID是0xfec7, indicate characteristics的UUID是0xfec8. 这两个是必须的。而read characteristics UUID不支持也没有问题。
3.&&&& 蓝牙Airsync协议交互
  满足以上两个条件代表已经能够跟手机微信进行数据通信了。但是交互过程是一个协作的过程,就像我们访问业务系统一样也要先登陆,再初始化后,才能进行正常的业务通信啊。那么登陆和初始化我们可以理解为应用控制信令,而后续的数据通信也是应用数据通信。
  蓝牙Airsync协议使用protobuf技术进行封包和解包,详见《》。
  登陆时的数据参数格式是:
  微信支持两种登陆身份认证,加密和不加密。这里只讨论简单的不加密认证好了。不加密时,我们一般用MAC地址方式登陆,即将AeSine付空值,AuthMethod赋值为EAM_macNoEncrypt.
  Author会收到手机微信的回复,在加密时收到的是一个用于之后通信的秘钥,但在不加密是可以忽略。
2) 初始化
  初始化的目的是外设生成一个随机数,以后每次通信后,该数值都会自动加1;另外,在初始化的回复中,手机微信可以告诉外设手机微信当前的用的手机操作系统的版本、当前时间、微信用户ID等等。以便于外设记录用户的信息。
  初始化的数据参数格式是:
&&&&&& 初始化成功之后就可以正常通信了。
&&&&&& 微信提供一个叫做airsyncDebug的工具用于调试,如果能正常与它连接通信,那就代表着可以跟微信进行正常通信了。
三、蓝牙Airsync协议学习开发步骤 & & &
1.&&&& 初步理解微信规范《蓝牙外设协议》。
2.&&&& 理解本文
3.&&&& 根据本文的分析理解微信官方实现的基于NRF81522平台的外设例程。
4.&&&& 在自己的蓝牙单芯片平台开发实现Airsync协议,并结合airsyncDebug进行调试。
  你将会事半功倍!祝好运!
  更多嵌入式Linux和物联网原创分享,请关注微信公众号:嵌入式企鹅圈
阅读(...) 评论()& & & &Protocol buffer是Google出品的一种轻便高效的结构化数据存储格式。可对结构化数据进行序列化,并具有语言无关、平台无关等特点。在通信协议和数据存储等领域已经得到广泛的应用。眼下其已经提供&C/C++、Java、Python 等语言的 API。
一、Protocol buffer和XML
在数据通信传输时,一般须要将结构化的数据序列化成流进行传送,接收方再反序列化为原始格式数据进行处理。在Web通信领域,XML应用算是最通用的了。在时间性能上,尽管XML的序列化开销还可以。可是反序列化的效率是比較差,而Protocol buffer的反序列化效率是比較高的;在空间性能上,Protobuffer採用了可变长的数据编码格式。比XML的字符格式要高效得多。Google集群要处理PB级数据。Protocolbuffer可以在时间和空间性能上有所改进,在总体效益而言就是相当可观的。
正是基于以上原因。微信和蓝牙外设的通信协议採用了Protocol buffer对消息包体进行打包。本文的目标是讲述Protobuffer在蓝牙微信协议中的应用,有助于理解微信蓝牙协议,对微信发给蓝牙外设的消息数据流进行反序列化,得到原始的结构化格式数据。因此语法也是环绕微信蓝牙协议包展开。更加具体的语法请百度相关内容或者找笔者探讨。
二、微信蓝牙外设协议通用格式
微信蓝牙使用流进行传输,在流上传输的是一个接着一个的业务逻辑的数据包。把设备发往厂商server或者微信server的请求包称为Req,回复包称为Resp。一个请求相应一个回包。把厂商server或者微信server主动发往设备的请求包称为PushReq。
包结构由定长包头和变长包体组成。当中包体即由Protocol buffer进行打包。
当中,定长包头为8个字节,bMagicNumber为0xFE。bVer为版本号01;nLength为包长,包含包头和包体的长度。nCmdId为命令编码,如登陆授权,初始化。发送数据。push推送等等;nSeq为序列号。PushReq包的序列号固定为0。其它请求和回复包的序列号务必保持一致。每次请求后序列号加1.
以厂商server主动发数据给设备的PushReq包为例来说明变长包体,其相应定长包头的nCmdId为ECI_push_recvData = 30001。包体包含下面三个部分:
1) Push包标识
2) 自定义数据,指的是业务层自定义的数据格式形成的数据。
3)& 数据类型。如厂商自己定义的数据,还是微信clientHtml5的数据等
三、Protobuffer的语法表述
Protobuffer对push_recvData包的表述例如以下:
Message类似C语言的struct数据结构,是Protobuffer消息定义的keyword。RecvDataPush是消息的名称。
Required前缀表示该字段必须在序列化之前赋值。optional前缀表示能够不赋值。
BasePush BasePush是message的第一个字段field。前者代表数据类型,后者是名称,当中BashPush在协议中是这样定义的:
Message BashPush{} 其意味着里面没有数据项。BashPush在打包过程中仅仅会出现数据类型,事实上也是代表着一种push标识。
Bytes Data是第二个字段field,为字符串。名称是Data。
EmDeviceDataType type是第三个字段field,为设备数据类型。当中EmDeviceDataType是一个enum类型。例如以下:
1,2,3代表字段在序列化后布局中的位置index,第一个位置是BashPush,接着是Data、type。
四、Protobuffer打包
Protobuffer打包有下面要素和规则:
1.使用Varints算法表示数字。Varints是一种紧凑表示数字的方法。Varints中每个字节的最高位是有特殊含义的,假设是1,则表示兴许的字节也是该数字的一部分;假设是0,则结束。所以假设表示小于128的数值能够用一个字节,假设大于等于128的数字则要用很多其它的字节进行表示。
2. Protobuffer有下面数据类型
<img src="http://img.blog.csdn.net/13732?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
Type表示相应数据类型序号,当中Varint相应的数据类型包含int32,int64,enum等等。type序号为0,其都使用Varints进行表示。String,bytes,message类型相应的type序号为2.
3. Protobuffer打包即是将message通过一系列的key-value对来表示。而key就是每一个message中各字段的index(并做一定运算)。value依据类型的不同会有不同的表现形式。
当中key = field&&3 | type。field即字段的index,而type是字段的数据类型序号。
而value,在数据类型为Varint时,直接为字段的赋&#20540;,依照Varints算法进行编码。在其它类型时就是“长度&#43;原始内容编码”。
五、PushReq包分析
我们通过微信提供的AirSyncDebugger2.1.0.apk来分析Protobuffer对数据包的序列化。该APP用于微信和蓝牙外设的通信调试,其封装了微信蓝牙的协议,一般先用该APP调通蓝牙协议。再和后台server联调。如果我们自己定义的消息内容为fe cf 00 01 00 0c 20 01 00 00 00 00,即相应第二个字段bytesData,该消息内容是上一篇文章中server控制亮灯所发的消息,后台server和蓝牙外设的消息协议是自己定义的。AirSyncDebugger对PushReq包的序列化例如以下:
序列化过程分析例如以下:
固定包头(不受Protobuffer控制):
Magic : fe
Version: 01
Length : 00 1A。即包体和包体的总长度为26字节。
Cmdid : 75 31,十进制就是30001。即ECI_push_recvData包
Seq : 00 00 push包的序列号都是00 00
变长包体(Protobuffer控制打包,十六进表示):
0A: BasePush的field是1, &#20540;类型message的序号type为2,所以是0x1&&3|0x02 = 0x0A
00 : 即&#20540;长度为0,BasePush&#20540;为空,事实上就是一种标识。
12:data的field是2。&#20540;类型bytes的序号为2,所以是0x2&&3|0x2=0x12
0C:& data的长度是12
Fe cf 00 01 00 0c20 03 00 00 00 00 : data的内容,即我们自己定义的消息。
18: Type的field是3,&#20540;类型enum的序号为0。所以是0x3&&3|0=0x18
00:Type的&#20540;,由于enum属于Varint的一种,所以不须要长度,直接用&#20540;表示,0代表厂商自己定义数据。
六、基于微信硬件公众平台的智能控制方案开发专栏介绍
&&&&&& 接下来嵌入式企鹅圈会将陆续公开基于微信硬件公众平台的智能控制开发技术细节,大致内容包含:
1. 物联网架构和场景分析(已发)
2. 基于微信硬件公众平台的智能控制开发流程(已发)
3. 云server搭建和公众号配置
4. 公众号菜单设置
5. 微信消息传递过程和微信设备接入接口协议
6. 微信硬件平台后台服务开发
7. 微信蓝牙协议和授权、绑定过程
8.Protocol buffer序列化及其在微信蓝牙协议中的应用(已发)
9. 蓝牙外设控制开发
谢谢支持嵌入式企鹅圈:
<img src="http://img.blog.csdn.net/30915?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
阅读(...) 评论()

我要回帖

更多关于 微信蓝牙接口 的文章

 

随机推荐