SYD8801微信接入开始【微信蓝牙精简协议】【AirSync开发文档】

SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/

 

本文摘录于:http://iot.weixin.qq.com/wiki/new/index.html?page=4-3

只做学习之用!

 

微信蓝牙精简协议

 

1.概要

目前微信蓝牙精简协议支持智能手环等计步类设备接入微信运动,具体框架如下:

微信蓝牙计步器Profile协议是基于GATT的协议,该协议对设备的硬件能力要求较低,并且厂商不需要有和微信对接的后台服务器(即只需要开发设备)。 该profile可以让计步器和微信连接,并传输步数,公里数,卡路里,运动目标等。

2.微信蓝牙精简协议文档

广播和MAC特征值

设备需要广播包带上微信的service,并在manufature data里带上mac地址。 微信Service uuid:0xFEE7 manufature specific data:需以MAC地址(6字节)结尾。并且manufature specific data长度需大于等于8字节(最前两个字节为company id,没有的话随便填)。 微信service下面需包含一个读特征值,uuid为:0xFEC9,内容为6字节MAC地址(ios系统其他软件连上设备之后,微信会去读该特征值,以确定设备MAC地址)。

特征值概要

计步的profile放在微信的service下面,由两个特征值构成:

特征值名称current_pedometer_measurement
uuid0xFEA1
权限Read;Indicate和Notify二选一,也可都支持
是否必选必选
说明实时计步信息,包括:步数,距离,卡路里
特征值名称target
uuid0xFEA2
权限Read;Write;Indicate
是否必选可选
说明运动目标

特征值内容

所有特征值内容里面的字节序都为小端字节序。

current_pedometer_measurement

current_pedometer_measurement的值由4部分组成

类型说明
FlagUnit80x01:步数(必选) 0x02:距离(可选) 0x04:卡路里(可选)如0x05表示含有步数和卡路里
StepCountUint24步数
StepDistancerUint24走了多远,单位米
StepCalorieUint24卡路里

说明: 1.距离和卡路里是可选的,可能出现也可能不出现 如果只有步数,那么值为:01 (步数)10 27 00(1万步) 如果有步数和距离,那么值为:03(步数,距离)10 27 00(1万步)70 17 00(6公里) 其他情况以此类推。 2.时间值以手机时间为标准,即手机收到数据的那一刻就认为是这个数据的时间。

target

target的值为

类型说明
FlagUint80x01:步数(必选)
StepCountUint24步数

说明: 1.如目标为一万步,那么值为:01(步数) 10 27 00(1万步) 如果手机往设备写入目标值,设备要更新。如果设备更新了目标值,要通知手机。

时序

3.文档及工具下载

微信运动接入精简设备用例 微信蓝牙协议调试工具AirSyncDebugger-说明文档v2.2.0 AirSyncDubugger2.2.1

 

AirSync开发文档

本文摘录于:http://iot.weixin.qq.com/wiki/new/index.html?page=4-2-2

只做学习之用!

 

 

AirSync开发文档

 

1. 概要

该章节规范了蓝牙设备和手机上的微信的通信协议。 AirSync协议支持经典蓝牙和4.0 BLE蓝牙,目前支持ios和andriod两个系统,后续会扩展到其他系统。 协议架构图如下,其中厂商服务器和外设,由厂商开发完成。微信会提供服务器的接口以对接厂商的服务器,会提供手机的接口(如本文规定的蓝牙协议)以对接厂商的外设:

●主要功能 该协议打通了设备和厂商服务器之间的数据链路,也就是支持将设备上的数据发送到厂商的服务器上,也支持将厂商的数据发送到设备。厂商的数据对于微信来说,是黑盒,微信不对设备数据做分析。 该协议也打通了设备和微信服务器之间的数据链路。设备和微信服务器之间的数据格式由微信规定,例如登录,新消息通知等。 ●蓝牙BLE模拟成流 微信支持蓝牙BLE。 微信规定了蓝牙BLE设备需要先模拟成流(即stream,输入输出流)。经典蓝牙的RFCOMM,就是一个流。流具有的特性有: —— 可以传输无限长度的数据 —— 双工,读写可以并发,互不干扰 显然,蓝牙BLE无法传输无限长度的数据,为了实现这个目的,需要定义一个规范。 蓝牙设备需暴露两个特征值(Characteristics):Write特征值,Indication特征值。蓝牙设备从Write特征值接受数据,从Indication特征值发送数据。 Indication特征值类型是bytes。 这里我们约定,把一个特征值一次传输的数据,称为一帧(不同类型的特征值一次传输的数据长度是不一样的)。 注意:应用层上的数据包(例如1k大小),会分散成许多帧来传输。 蓝牙设备写过程: a.分帧:假设蓝牙手环上有1k数据,要发给手机微信。由于一个特征值长度有限(如20个字节),显然需要分多次才能传输完成。1k数据,要分成1024字节/ 20字节=51 个帧。剩下的4个字节,不足一帧(20个字节),需补齐为一帧并对剩下的16个字节赋0。总共是52帧。 b.发送第一个帧:把第一个帧的内容放入特征值里面。然后通知手机读取数据,通知有两种方式,Indication 和notify,这里使用Indication方式,即带响应的通知。当通知完成的时候,可以认为手机已经读完数据。这就完成了发送第一个帧 c.按照2的步骤,依次发送剩下的帧。 蓝牙设备读过程: 当蓝牙设备发现读特征值收到数据的时候,就接收数据,并追加到设备的buf里。 注意: 蓝牙设备必须等微信app订阅了Characteristics之后,才能indicate数据,否则会造成设备发送数据丢失的问题。

2. 外设协议

●前提 厂商需先开通微信公众平台的硬件号功能。 厂商需先在微信硬件平台授权设备,具体接口请参考: 设备授权接口 ●设备和广播 为了和微信能够通信,设备的广播包需符合以下的格式: 低功耗蓝牙(android&ios)设备需要广播: a.微信规定的service uuid(具体见附录)。 b.厂商自定义字段里,包含MAC地址(具体见附录)。 c.包含指定的Characteristics(具体见附录)。 Andriod经典蓝牙设备需要广播: a.暴露一个指定uuid的rfcomm服务(具体见附录)。 b.厂商自定义字段里,包含MAC地址(具体见附录)。 Ios经典蓝牙需要通过mfi认证,并且SerialNumber需为MAC地址(字符串形式)。 设备可分为两种: 可确认设备:如有按钮,或者可以双击,或者有可检测翻转等传感器,可与人交互的设备。大部分设备属于可确认设备。 无法确认的设备:即没有按钮等传感器,无法与人交互的设备。这种设备很少,目前的市面上设备,有很多是要设备做出确认之后(如长按某个按钮,或者靠近手机),才会进行设备和用户的绑定。 相应的,广播包有两种: 普通包:我们把设备正常情况下无时无刻广播的包成称为普通包 确认包:当用户进行设备确认时(如双击手环,或者按按钮),广播的特殊的包称为确认包。微信规定了微信认识的普通包和确认包的格式:通过manufature data来区别(具体见附录)。 ●绑定 用户绑定设备有两种方式:扫码绑定,厂商服务器绑定,这两种方式都需要先向微信公众平台注册授权设备(具体api参见公众平台文档)。 (1)扫码绑定 用户通过扫描设备二维码绑定设备(获取二维码的方法见公众平台文档)。 用户场景: 用户打开扫一扫界面,扫码设备二维码,出现公众号页面。用户点击关注,进行绑定设备。扫码绑定并不需要设备在身边。 (2)厂商服务器绑定: 厂商可通过微信公众平台提供的接口,绑定厂商指定的用户和设备。该功能给厂商比较大的自由,可自定义绑定的流程和界面(通过html5)。该功能目前需要通过本协议的jsapi来实现。 绑定的用户场景和技术细节详见本文档jsapi章节。 ●扫描和连接 进入特定界面后(如具有硬件功能的公众号界面),微信会开始扫描设备。当设备广播符合微信定义的广播包时,则微信可以扫描到设备。 扫描到设备后,微信会连接设备(Ios经典蓝牙需要用户手动在设置界面里面连接上设备)。 当连上设备之后,微信和设备之间开始传输数据。数据的具体格式见下面章节。 ●流 经典蓝牙使用RFCOMM通信(是个流),蓝牙BLE也模拟成流。 ● 包 流之上运载的是一个紧接着一个的业务逻辑的数据包。 数据包的发送方和接受方:设备<->厂商服务器,或者设备<->微信服务器。 把设备->厂商服务器/微信服务器的请求称为Req,回包称为Resp。一个请求,对应着一个回包。 把厂商服务器/微信服务器->设备的请求称为PushReq,没有回包(即没有PushResp这样的包)。 ●包结构 由定长包头和变长包体组成。

包的二进制例子见附录。

字段

类型

说明

bMagicNumber

unsigned char

填0xFE

bVer

unsigned char

包格式版本号,填1

nLength

unsigned short

为包头+包体的长度

nCmdId

unsigned short

命令号,如ECI_req_auth,ECI_resp_sendDataToManufacturerSvr等

nSeq

unsigned short

递增。

一个Req对应一个Resp,并且它们的nSeq相同,并且永不为0。

Push的nSeq永远为0;

●变长包体 为Protobuf(protobuf的介绍见附录)打包的结构。例如AuthReq。 一个包体里面只有一个Req,或者一个Resp,或者一个PushReq。 每个Req/Resp/PushReq都有对应的EmCmdId,例如AuthReq的命令号为ECI_req_auth。 具体的定义见附录。 ●加密的身份验证 微信支持身份验证和加密,以使得厂商的数据更加安全。 加密算法选用aes 128位,并使用cbc模式,pkcs7填充。初始向量为密钥。 具体验证和加密的步骤如下: 设备需要烧一个Key(128位)到硬件上,微信服务器也要记录下这个Key。一个设备(deiveId+deviceType唯一确定一个设备),对应一个Key。 key要保护好(类似用户密码,银行卡账号密码),千万不要印刷出来或者打印出来。 另外有一个MD5(deviceType+deviceId),如果设备算MD5很麻烦的话,建议先算好,直接烧进设备里面。该MD5类似于用户名。 对于设备来说,手机和服务器可看成一个黑盒。设备和手机服务器之间,通过Auth命令,使用key,最终,把sessionKey下发给到设备。 Auth的步骤为: 设备发送AuthReq,里面的字段有MD5(deviceType+deviceId),另一个字段为AES加密的一段buffer(具体字段细节在附录描叙)。 微信发送回包AuthResp,里面的字段有用AES加密的含有sessionkey的一段buffer(具体字段细节在附录描叙)。设备解密这段buffer可得到SessionKey。 设备和手机之间,就通过sessionKey来加解密包。 AuthReq, AuthResp之后的所有命令,例如InitReq, InitResponse,SendDataRequest,SendDataResponse,RecvDataPush等都需要加解密。 加密只针对变长包体,不需要加密定长包头。 为了提高安全性,设备可再进一步的验证手机是否可信。 设备在InitReq里填入Challeange(一个4字节的随机数random4),手机将在InitResp里面返回ChalleangeAnswer(一个4字节的数,值为crc32(random4))。设备验证ChalleangeAnswer是否正确。如果是,说明手机是可信的。 身份验证和加解密大体的流程图为:

另外有一些细节: 当sessionKey过期,手机对设备的所有请求都返回错误码 EEC_sessionTimeout,要求设备重做一次auth。 当发现解密设备的包失败时,返回 EEC_decode。这种情况下,通常是sessionkey过期,或者是设备程序有问题。 ●不加密的身份验证 微信客户端同时支持不加密的方式,以降低设备厂商的接入难度,加快开发产品的进程。 不加密的方式下,设备和微信之间的通信的安全级别,将与设备和系统原生的蓝牙api之间的通信的安全级别一样。为了确保厂商设备和服务器的数据安全,厂商需自行实现安全机制。 不加密有两种方式: MD5认证:使用MD5(deviceType+deviceId)和微信认证,如果设备算MD5很麻烦的话,建议先算好,直接烧进设备里面。该MD5类似于用户名。这种方法要求产线上对不同的设备需要烧写不同的MD5。 MAC地址认证:使用MAC地址和微信认证。Mac地址类似于用户名。这种方法不需要产线上对设备烧写额外的东西(MAC地址在原来的产线上本来就是要烧进设备的)。该方法减低了产线的难度,但安全性不如MD5认证。 步骤如下: 将AuthReq里的AesSign字段付空。 如果是用MD5登录,则赋值Md5DeviceTypeAndDeviceId字段,且AuthMethod=EAM_md5AndNoEnrypt,如果是MAC地址登录,则赋值MacAddress字段,且AuthMethod=EAM_macNoEncrypt。 发送AuthReq。 收到AuthResp之后,忽略掉AesSessionKey字段。 将InitReq里的Challeange字段随便付一个值。发送InitReq。 收到InitResp,忽略掉ChalleangeAnswer字段。 随后的包都不需要加解密。 ●会话约定 设备连上微信之后,需要发送AuthReq,等收到成功的回包之后,接着还要发送InitReq,并收到成功的回包之后,才能正常发送数据。如果设备没有auth,手机对设备的所有请求都返回错误码 EEC_needAuth。 当出现解包异常的时候,直接断开连接。 Push类的包seq永远为0。Req类和Resp类的包的seq永不为0。 服务器可随时发送Push包。 厂商服务器发送的Push包(注意Push包是没有回包的,即没有PushResp),如果需要设备的回包,需要由厂商自己实现。 具体方法如:厂商发送RecvDataPush给设备,设备收到push后,向厂商服务器发送一个SendDataRequest。这时厂商服务器可知道设备收到了push,并且可以从Req里取得设备的回应数据。 ●时序 时序图请见附录。 ●Read Characteristics 为了支持同一手机上一个app连接了设备后,微信还能搜素并连接到设备的情况,设备需要在微信的service下面,暴露一个read character,内容为6字节的MAC地址。当ios上的其他app连接上设备时,设备不会再广播,微信会读取该特征值,以确定是否要连接该设备。 ●其他 目前规定了一些基础的协议,更多的协议等待补充。

3. Protobuf协议

变长包体部分,使用的是Protobuf定义的协议。Protobuf文件见附录。里面规定了设备和微信客户端之间的命令。 ●命令列表

名称

描叙

Auth

登录

Init

初始化

SendData

设备发送数据给厂商或微信公众平台或微信客户端。

当type为空或者等于0时,表示发送给厂商服务器。

当type为10001时,表示发送给微信客户端html5设备会话界面。

当type为其他时,表示发送给公众平台服务器。具体的定义请看 附录:微信公众平台proto文件。举个例子,type等于1时,表示手环数据。

RecvDataPush

厂商或微信客户端或微信公众平台发送数据给设备

当type为空或者等于0时,表示厂商发送设备。

当type为10001时,表示收到微信客户端html5设备会话界面的数据。

当type为其他时,表示公众平台发送给设备。具体的定义请看 附录:微信公众平台proto文件。举个例子,type等于1时,表示手环数据。

SwitchViewPush

微信客户端进入退出界面的通知

SwitchBackgroudPush

微信客户端进入退出后台的通知

●错误码 Proto里的错误码

EEC_system

微信客户端一般的错误

EEC_needAuth

设备未登录。需要登录。

EEC_sessionTimeout

sessionKey超时。需要重新登录。

EEC_decode

微信客户端解proto失败。可能是设备端打包代码有bug。

EEC_deviceIsBlock

微信客户端一段时间之内禁止设备的请求。通常是设备某些异常行为引起,如短时间多次登录,大量发送数据等。

EEC_serviceUnAvalibleInBackground

ios处于后台模式,无法正常服务

EEC_deviceProtoVersionNeedUpdate

设备的proto版本过老,需要更新

EEC_phoneProtoVersionNeedUpdate

微信客户端的proto版本过老,需要更新

EEC_maxReqInQueue

设备发送了多个请求,并且没有收到回包。微信客户端请求队列拥塞。

EEC_userExitWxAccount

用户退出微信帐号。

为正数时

具体见微信公众平台。

固定包头里的错误码: 固定包头里的错误码放在cmdid字段里。当设备收到这样的错误码后,可以通过seq查出是那个命令失败。目前只有一个错误码。

ECI_err_decode

微信客户端解密包体失败。

通常是因为sessionKey过时,需要重新做一次auth,也可能是设备加密代码有bug。

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值