Protocol buffer序列化及其在微信蓝牙协议中的应用
Protocol buffer是Google出品的一种轻便高效的结构化数据存储格式,可对结构化数据进行序列化,并具有语言无关、平台无关等特点,在通信协议和数据存储等领域已经得到广泛的应用。目前其已经提供 C/C++、Java、Python 等语言的 API。
一、Protocol buffer和XML
在数据通信传输时,一般需要将结构化的数据序列化成流进行传送,接收方再反序列化为原始格式数据进行处理。在Web通信领域,XML应用算是最通用的了。在时间性能上,虽然XML的序列化开销还可以,但是反序列化的效率是比较差,而Protocol buffer的反序列化效率是比较高的;在空间性能上,Protobuffer采用了可变长的数据编码格式,比XML的字符格式要高效得多。Google集群要处理PB级数据,Protocolbuffer能够在时间和空间性能上有所改进,在整体效益而言就是相当可观的。
正是基于以上原因,微信和蓝牙外设的通信协议采用了Protocol buffer对消息包体进行打包。本文的目标是讲述Protobuffer在蓝牙微信协议中的应用,有助于理解微信蓝牙协议,对微信发给蓝牙外设的消息数据流进行反序列化,得到原始的结构化格式数据。因此语法也是围绕微信蓝牙协议包展开。更加详细的语法请百度相关内容或者找笔者探讨。
二、微信蓝牙外设协议通用格式
微信蓝牙使用流进行传输,在流上传输的是一个接着一个的业务逻辑的数据包。把设备发往厂商服务器或者微信服务器的请求包称为Req,回复包称为Resp,一个请求对应一个回包。把厂商服务器或者微信服务器主动发往设备的请求包称为PushReq。
包结构由定长包头和变长包体组成,其中包体即由Protocol buffer进行打包。
其中,定长包头为8个字节,bMagicNumber为0xFE;bVer为版本01;nLength为包长,包括包头和包体的长度;nCmdId为命令编码,如登陆授权,初始化,发送数据,push推送等等;nSeq为序列号,PushReq包的序列号固定为0,其他请求和回复包的序列号务必保持一致,每次请求后序列号加1.
以厂商服务器主动发数据给设备的PushReq包为例来说明变长包体,其对应定长包头的nCmdId为ECI_push_recvData = 30001。包体包括以下三个部分:
1) Push包标识
2) 自定义数据,指的是业务层自己定义的数据格式形成的数据。
3) 数据类型,如厂商自定义的数据,还是微信客户端Html5的数据等
三、Protobuffer的语法表述
Protobuffer对push_recvData包的表述如下:
Message类似C语言的struct数据结构,是Protobuffer消息定义的关键字。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有以下数据类型
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时,直接为字段的赋值,按照Varints算法进行编码;在其他类型时就是“长度+原始内容编码”。
五、PushReq包分析
我们通过微信提供的AirSyncDebugger2.1.0.apk来分析Protobuffer对数据包的序列化。该APP用于微信和蓝牙外设的通信调试,其封装了微信蓝牙的协议,一般先用该APP调通蓝牙协议,再和后台服务器联调。假设我们自定义的消息内容为fe cf 00 01 00 0c 20 01 00 00 00 00,即对应第二个字段bytesData,该消息内容是上一篇文章中服务器控制亮灯所发的消息,后台服务器和蓝牙外设的消息协议是自定义的。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, 值类型message的序号type为2,所以是0x1<<3|0x02 = 0x0A
00 : 即值长度为0,BasePush值为空,其实就是一种标识。
12:data的field是2,值类型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,值类型enum的序号为0,所以是0x3<<3|0=0x18
00:Type的值,因为enum属于Varint的一种,所以不需要长度,直接用值表示,0代表厂商自定义数据。
六、基于微信硬件公众平台的智能控制方案开发专栏介绍
接下来嵌入式企鹅圈会将陆续公开基于微信硬件公众平台的智能控制开发技术细节,大致内容包括:
1. 物联网架构和场景分析(已发)
2. 基于微信硬件公众平台的智能控制开发流程(已发)
3. 云服务器搭建和公众号配置
4. 公众号菜单设置
5. 微信消息传递过程和微信设备接入接口协议
6. 微信硬件平台后台服务开发
7. 微信蓝牙协议和授权、绑定过程
8.Protocol buffer序列化及其在微信蓝牙协议中的应用(已发)
9. 蓝牙外设控制开发
…
Protocol buffer序列化及其在微信蓝牙协议中的应用的更多相关文章
- Protocol Buffer 序列化原理大揭秘 - 为什么Protocol Buffer性能这么好?
前言 习惯用 Json.XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存 ...
- Protocol Buffer序列化Java框架-Protostuff
了解Protocol Buffer 首先要知道什么是Protocol Buffer,在编程过程中,当涉及数据交换时,我们往往需要将对象进行序列化然后再传输.常见的序列化的格式有JSON,XML等,这些 ...
- Protocol Buffer序列化对比Java序列化.
初识 Protocol Buff是谷歌推出的一种序列化协议. 而Java序列化协议也是一种协议. 两者的目的是, 将对象序列化成字节数组, 或者说是二进制数据, 那么他们之间有什么差异呢. proto ...
- Protocol Buffer序列化/反序列化---初体验(java版)
今天闲遐时学习了 Protocol Buffer 在网上看到了许多资料,其中不泛精品,想要详细了解的请看文章结尾的友情链接,我这里就做加深印象,快速入门的一个完整的demo,仅此而已. 学完你可以得到 ...
- 蓝牙协议中的SBC编码
一.从信息的传输说起  上图是一个典型的蓝牙耳机应用场景.手机上的音频信息经过编码以后通过蓝牙协议被蓝牙耳机接收,经过解码以后,蓝牙耳机成功获取手机上的音频信息,然后再转化为振动被人耳识别.这是一个 ...
- 蓝牙协议中的SBC编解码原理和仿真
一.SBC的原理 SBC是subband codec的缩写,中文叫做次频带编码,也叫子带编码.其基本原理是把信号的频率分为若干子带,然后对每个子带进行编码,并根据每个子带的重要性及特点分配不同的位数( ...
- 以蓝牙开发的视觉解读微信Airsync协议
微信硬件平台使用蓝牙作为近场控制的连接件,并拟定了<微信蓝牙外设协议>.这份协议更像一个标准,用于规范微信和蓝牙外设之间的数据交互场景和接口.但从开发者来看,要完全读懂这份协议,恐怕需要熟 ...
- Android:Google出品的序列化神器Protocol Buffer使用攻略
习惯用 Json.XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式 ...
- 微信蓝牙BLE接入调试指引 硬件篇
1 平台框架简介 微信蓝牙BLE由三个模块组成,分别是蓝牙设备.微信和第三方服务器,如下图: 蓝牙设备与微信之间的通信是通过蓝牙GATT协议进行. 微信与第三方服器之间的通信是通过网络http 接口进 ...
随机推荐
- 脚本学习python和linux-shell和jQuery(javascript)
使用脚本可以方便管理,使用计算机. 打算学脚本来更好地用计算机系统,特别是Linux. 学python因为它开源,而且是C家族的语言,本来也是课程需要,再加上它确实很好,所以非常主打,之前看过perl ...
- shell调用shell
在默认条件下,执行shell文件会出现permission denied报错,一般是没有可执行权限.用chmod修改权限 chomd 777 score.sh //把所有权限给aa文件 777代表 ...
- 火狐无法访问本机IIS部署的网站,弹出:此地址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求 的解决办法
关于火狐浏览器访问本机IIS部署的网站弹出“此地址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求”这个错误(错误截图如下): 解决方法如下: 1.打开火狐浏览器, ...
- 微信小程序,大多数人误解的8个问题
作者:王安,数字天堂DCloud公司创始人兼CEO 注:本文内容包含技术.商业,不懂技术的读者可以只看商业相关的内容.本文仅代表作者一家之言,如有不同意见,欢迎留言讨论~ 8个误解 坊间所传的信息很多 ...
- html5 实现手机端相册浏览功能
原文地址:http://www.cootm.com/?p=710 在网上找到个浏览图片的jq插件,针对手机做的非常不错,看到乐享的微信微站新开发的功能就是这个,特此分享下! 时间匆忙,没做代码分析,勿 ...
- 使用Raphael 画图(二) 扩展的图形 (javascript)
看这文章前,建议先看第一编文章<使用Raphael 画图(一) 基本图形 (javascript)>. 在Raphael基础上扩展的图形: 要运行该例子要引入附件的2个js包.(g.rap ...
- Day11 线程、进程、协程
创建线程第一种:import threadingdef f1(arg): print(arg) t = threading.Thread(target=f1, args=(123,))#t.start ...
- 【Java】Hibernate4实战 之 第一部分Hibernate入门
Hibernate是什么:ORMapping的原理 Hibernate是轻量级的ORMapping框架. ORMapping基本规则: 类和表映射. 实例和数据库表中的一条数据映射. 实例的属性和数据 ...
- Zabbix的集中式监控
相对于传统的ZABBIX硬件系统级监控(CPU,内存,硬盘,网卡),应用级的监控就显得有些复杂了. 如果对不同的应该来不同的应用,配置会很多的. 如果我们能在一个指定的AGENT上监控所有的APACH ...
- 一句话改变TWinControl控件的left坐标的前世今生(入口函数是SetBounds,然后调用SetWindowPos起作用,并发消息更新Delphi的left属性值)
Delphi的重要属性,主要是Enable, Visible, Color, left等等.这里分析left,因为TWinControl里有些覆盖函数的原因,虽然起点都是TControl.SetLe ...