Leshan 源码分析

简介

Leshan是iot.eclipse.org推出的辅助实现LwM2M的开源工具库集合。以Java实现,使用EDL1.0(BSD)EPL1.0的License。目前(2018/11)Leshan的实现是基于LwM2M 1.0.2的。

介绍:https://www.eclipse.org/leshan/
源码:https://github.com/eclipse/leshan

iot.eclipse.org下其他相关项目:

编译与运行

下载源码:

#using ssh
git clone [email protected]:eclipse/leshan.git

or

#using https
git clone https://github.com/eclipse/leshan.git

编译(需安装maven,使用Ubuntu 18.04和OpenJDK 10):

#install maven
sudo apt install maven
#compile
mvn clean install

注:使用openjdk-8-jdk编译时如遇到surefire报错,可以参考stackoverflow,要解决此问题,可以拷贝此settings.xml到**~/.m2/**。如该目录下已有settings.xml文件,则需要自行合并文件内容。

运行Server:

java -jar leshan-server-demo/target/leshan-server-demo-*-SNAPSHOT-jar-with-dependencies.jar

此时可以通过http://localhost:8080访问Server控制界面。

运行Bootstrap Server:

java -jar leshan-bsserver-demo/target/leshan-bsserver-demo-*-SNAPSHOT-jar-with-dependencies.jar 

本机运行Client:

java -jar leshan-client-demo/target/leshan-client-demo-*-SNAPSHOT-jar-with-dependencies.jar

在网络中其他机器上运行Client:

java -jar leshan-client-demo-*-SNAPSHOT-jar-with-dependencies.jar -u xxx.xxx.xxx.xxx:5683

在网络中其他机器上运行Client时需要注意

  • jar路径和名称需正确
  • xxx.xxx.xxx.xxx需替换成正确ip
  • 5683是服务端默认端口,需保持正确

源码树分析

  • leshan-all:目录下所有工程的编译 / 打包配置,依赖于 leshan-client-cf 和 leshan-server-cf
  • leshan-bsserver-demo:bootstrap server demo,不可直接用于生产环境,仅供参考
  • leshan-client-cf:客户端cf接口,依赖 leshan-core-cf / leshan-client-core 以及 californium 相关
  • leshan-client-core:leshan client对象,依赖于 leshan-core
  • leshan-client-demo:client demo,不可直接用于生产环境,仅供参考
  • leshan-core:leshan基本数据结构及接口
  • leshan-core-cf:leshan中针对californium的抽象,依赖于 leshan-core 及 californium 相关
  • leshan-integration-tests:集成测试
  • leshan-server-cf:服务端cf接口,依赖 leshan-core-cf / leshan-server-core 以及 californium 相关
  • leshan-server-cluster:集群实现
  • leshan-server-core:leshan server对象,依赖于 leshan-core
  • leshan-server-demo:server demo,不可直接用于生产环境,仅供参考

从依赖关系分析,可参考下图: 源码树

leshan-client-demo 和 leshan-server-demo 属于demo性质,可以参考,但不能直接使用于生产环境。
californium 是CoAP底层框架,也无需深入研究,只需要了解其接口。
要实现自己的server / client,需要基于 leshan-server-cf 和 leshan-client-cf 实现。
初步的说明在Getting-started。Client另一种实现方式是基于Wakaama

注:cf 即是californium framework的简写。

源码初步分析

leshan-core

leshan-core是leshan的基础核心,包括:

  • src/main/resources/models:LwM2M协议定义的各种profile
  • org.eclipse.leshan,leshan基础类,可以认为是一些POJO和常量定义
  • org.eclipse.leshan.core,核心数据结构,包括各种基础工具类
  • org.eclipse.leshan.json,Json相关数据结构及工具类
  • org.eclipse.leshan.tlv,TLV指的是Type-Length-Value,这是TLV容器定义及编解码库
  • org.eclipse.leshan.util,各种基础工具类库,包含:
    • Base64
    • Hex
    • ThreadFactory
    • RandomString + String
    • Security / Credential
    • Validate简化验证判断写法

leshan-core-cf

org.eclipse.leshan.core.californium,实现了leshan在CoAP之上的抽象定义。

leshan-server-core

org.eclipse.leshan.server,实现了leshan的Server对象。

LwM2MServer提供了以下接口:

  • start / stop / destroy
  • send接口是泛型接口,有 同步 / 同步+timeout / 异步 / 异步+timeout 共4种形态
  • get "Registration / Observation / Presence" Service
  • getSecurityStore
  • getModelProvider

leshan-server-cf

org.eclipse.leshan.server.californium,包含接口类及实现类。

LeshanServerBuilder和LeshanBootstrapServerBuilder协助创建Server。

ObserveUtil协助处理Observation相关。

leshan-server-demo

该工程是作为server实现的范例,是前后端分离的模式,包含:

  • Server后端,放在src/main/java/org/eclipse/leshan/server/demo
    这是一个java应用,从LeshanServerDemo的main函数启动。
  • credentials资源,放在src/main/resources/credentials
  • models资源,放在src/main/resources/models,是LwM2M定义的模型profile
  • web app前端,放在src/main/resources/webapp
    这是一个独立的SPA,基于angular 1.2.17实现。
    该web app通过http请求发送到Server获取响应。

工程整体打包成jar运行。内置jetty作为web app的服务。后端跟前端通过REST接口传递消息。

后端对外提供的几个REST接口 / servlet(随时可能改变):

  • /event/*
  • /api/clients/*
  • /api/security/*
  • /api/objectspecs/*

leshan-client-core(略)

leshan-client-cf(略)

leshan-client-demo(略)

部分接口使用方法

从LeshanServer里面可以看出,主要提供了以下几个公开接口:

  • start() / stop() / destroy() - 启动停止相关
  • getRegistrationService() - 设备注册相关,可通过RegistrationService监听/查询设备注册/更新/下线情况
    • RegistrationListener
  • getObservationService() - 设备Observation相关
  • getPresenceService() - 设备Presence(在线情况?)
  • getSecurityStore() - Server安全设置?
  • getModelProvider() - Server支持的Model配置
  • send() - 通过此接口给设备发送Create/Read/Write/Delete/Execute/Discover/Observe+Request
  • getUnsecuredAddress() / getSecuredAddress() 获取Server访问地址
  • coap().getServer() 获取底层CoapServer实例

以下对于必要的接口进一步分析。

ModelProvider

LwM2M中把设备的所有可读/写/执行的属性视为Resource(资源)。将Resource根据其类型,组织在不同的Object(对象)中。OMA维护了一个Resource Registry(资源注册表)。可以通过已经定义的Object查看/下载其对应的Resource描述xml文件。从Resource Registry中可以看出Object ID的范围如下:

  • 0-1023,OMA定义的Objects
  • 1024-2047,OMA保留的Objects
  • 2048-10240,第三方标准组织或联盟定义的Objects
  • 10241-26240 / 26241-32768 / 32769-42768,公司/个人/供应商提供的Objects

说明:关于这部分内容我并不是非常理解,感觉似乎是第4部分可以自由定义,但要想不冲突,需要向OMA提交注册并得到认可,成为第3部分。

Resource ID也有范围,如下:

  • 0-2047,一般资源,每个Object中的Resource ID必须不同,但在不同Objects中可以重用
  • 2048-26240,公司/标准组织或联盟定义的资源
  • 26241-32768,私有资源,无需注册

举例来说,Device在LWM2M_Device-v1_0_3.xml中定义,其定义是It provides a range of device related information which can be queried by the LWM2M Server, and a device reboot and factory reset function。Device的Object ID是3,其中Model Number的Resource ID是1,Model Number的定义是A model identifier (manufacturer specified string)。对于LwM2M/Leshan来说,使用“/3/0/1”就可以唯一标识这个Resource(中间的0是Instance ID)。

从代码的角度来看,LeshanServer通过ModelProvider可以获得一个LwM2mModel。
在LwM2mModel中,包含Server所支持的所有ObjectModel的定义。
一个ObjectModel里面含有多个ResourceModel。
一个Client设备可能包含一个或多个ObjectModel。设备中的ObjectModel并不一定包含所有ResourceModel的值。
LeshanServer可以通过send()接口向Client设备发送各种请求,以创建/读取/写入/执行资源节点。

Top