在上一期的「独孤九剑」,华为全球培训中心平台专家 ICE青解读了「破索式」南向 Profile(戳蓝字回顾),今天来接着「破掌式」的学习,详细学习编解码的文件结构,线下开发的流程和要点。
编解码介绍
设备上报数据时,如果「数据格式」为「二进制码流」,则该产品下需要进行编解码插件开发;如果「数据格式」为「JSON」,则该产品下不需要进行编解码插件开发。
以 NB-IoT 场景为例,NB-IoT 设备和物联网平台之间采用 CoAP 协议通讯,CoAP 消息的 payload 为应用层数据,应用层数据的格式由设备自行定义。由于 NB-IoT 设备一般对省电要求较高,所以应用层数据一般不采用流行的 JSON 格式,而是采用二进制格式。但是,物联网平台与应用侧使用 json 格式进行通信。
因此,开发者需要开发编码插件,供物联网平台调用,以完成二进制格式和 JSON 格式的转换。
南向消息传输层使用 COAP/UDP,应用层的格式由设备自定义;
编解码插件由设备厂商提供,制造商 ID+设备型号唯一标识一个插件,NA 需要在北向配置设备的制造商 ID 和设备型号;
上行时编解码插件负责把消息解码成 json 格式,字段由 profile 定义;
下行时插件把 json 格式消息编码成设备识别的二进制数据;
Profile 一般由厂商定义。
开发环境准备
1、下载 Eclipse 安装包,直接解压缩到本地即可使用。
官网下载地址:http://www.eclipse.org/downloads
2、下载Maven插件包(zip格式),直接解压缩到本地。
官网下载地址:http://maven.apache.org/download.cgi
3、配置Maven插件
Maven的配置涉及Windows环境变量的配置与在Eclipse中的配置,环境变量的配置请参考网上资源,本节仅介绍Maven在Eclipse中的配置。
第一步:选择Eclipse菜单「Windows」->「Preferences」,打开Preferences窗口,选择「Maven」->「Installations」->「Add」。见下图:
第二步 选择 maven 插件包路径,点击「Finish」,导入 Maven 插件。
第三步:选择导入的 maven 插件,点击「OK」。
说明:
另外还需要进行 JDK 的安装和 Java 环境变量的配置,这里不详细讲解了,大家自行搜索。
开发编解码插件
1、导入编解码插件 DEMO工程
(1)下载编解码插件DEMO工程,在「source_code」文件夹中获取「codecDemo.zip」,将其解压到本地。
(2)打开Eclipse,右击Eclipse左侧「Project Explorer」空白处,选择「Import > Import...」。
(3)展开「Maven」,选择「Existing Maven Projects」,点击「Next」。
(4)点击「Browse」,选择步骤 1 解压获得的「codecDemo」文件夹,勾选「/pom.xml」,点击「Finish」。
2、开发插件
编解码插件DEMO 的 Maven 工程架构不需要修改,插件开发说明,对 DEMO 进行修改其中几个关键接口跟大家说下。
(1)decode 接口说明
decode 接口的入参 binaryData 为设备发过来的 CoAP 报文的 payload 部分。
设备的上行报文可以分为两种情况:设备上报数据、设备对平台命令的应答(对应下图中的消息①和⑤;消息④是模组回复的协议 ACK,无需插件处理)。两种情况下解码输出的字段不同。
(2)encode 接口说明
encode 接口的入参 json 格式数据,是平台下发的命令或应答。
平台的下行报文可以分为两种情况:平台命令下发、平台对设备上报数据的应答(对应下图中的消息②和③)。两种情况下编码输出的字段不同。
(3)getManufacturerId 接口说明
返回厂商 ID 字符串。IoT 平台通过调用该接口获取厂商 ID,以实现编解码插件和 Profile 文件的关联。只有厂商 ID 和设备型号都一致时,才关联成功。
(4)getModel 接口说明
返回设备型号字符串。IoT 平台通过调用该接口获取设备型号,以实现编解码插件和 Profile 文件的关联。只有设备型号和厂商 ID 都一致时,才关联成功。
3、接口实现注意事项
(1)接口需要支持线程安全
decode 和 encode 函数需要支持线程安全,不得添加成员变量或静态变量来缓存过程数据。
错误示例:多线程并发时 A 线程将 status 设置为 Failed,B 线程可能会同时设置为 Success,从而导致 status 不正确,引起程序运行异常。
正确示例:直接使用入参编解码,编解码库不做业务处理。
(2)禁止使用 DirectMemory
DirectMemory 是直接调用操作系统接口申请内存,不受 JVM 的控制,使用不当很容易造成操作系统内存不足,因此编解码插件代码中禁止使用 DirectMemory。
错误示例:使用 UNSAFE.allocateMemory 申请直接内存
(3)编解码插件的输入/输出格式
表 1 某款水表支持的服务定义:
那么数据上报时decode接口的输出:
收到数据上报后,平台对设备的应答响应,调用encode接口编码,输入为:
表 2 命令定义:
那么命令下发调用 encode 接口时,输入为:
收到设备的命令应答后,调用decode接口解码,解码的输出
(4)JDK支持的加密算法
摘要算法
对称加密算法
非对称加密算法
Base64
实现样例讲解
在编解码插件的 DEMO 工程中,提供了编解码插件样例,样例工程结构如下图所示。
本工程是一个 Maven 工程,开发者可在此样例工程的基础上修改如下部分,适配成自己需要的编解码插件。
1、Maven 的配置文件
在 Maven 的配置文件 pom.xml 文件中,根据命令规范,修改编解码插件的名字。
2、编解码代码实现
(1)在 ProtocolAdapterImpl.java 中,修改厂商 ID(MANU_FACTURERID)和设备型号(MODEL)的取值。IoT 平台通过厂商 ID 和设备型号将编解码插件和 Profile 文件进行关联。
(2)修改 CmdProcess.java 中的代码,实现插件对下发命令和上报数据响应的编码能力。
(3)修改 ReportProcess.java 中的代码,实现插件对设备上报数据和命令执行结果的解码能力。