Starfish -- 基于策略的WSN网络自治系统

嗯,看了一段时间的WSN网络管理,国内的文章基本都是笼统的提出一个框架,具体系统呢……没有。国外的要好很多,Manna这种开创式的架构没有实现情有可原,前两天看到一个帝国理工做的Starfish WSN[1](2010)网络管理系统,感觉不错,这里总结一下作为以后的参考。

Starfish 基于策略……这里的策略是什么?类似于专家系统中的rules,就是有一些前提条件,当满足条件时去执行一些动作。为什么要搞一个这种中间件出来?直接使用HARD-CODE + 条件判断不就行了?嗯,乍看起来是差不多,但仔细想想HARD-CODE的可拓展性实在是很差……当要加入新的策略时需要重新烧录节点(在不能动态加载二进制模块的前提下),改变策略对系统造成的开销实在太大。并且不方便网络管理员对网络进行管理,毕竟我们不能强求所有人都要进行嵌入式编程吧……使用中间件的形式使我们可以在语言的层次多一层抽象,使网络管理员使用类似脚本形式的语言(甚至是图形化的界面)就可以对网络进行管理。当然多一层抽象会多一层运行时开销以及解释程序也同样需要占用一些资源……但通过仔细的设计,这些复杂度与其带来的好处相比,嗯,微不足道!

嗯,Starfish由三大部分组成:(1)Finger2 policy system,由ponder2优化而来;(2)module library,嗯,就是与policy 直接交互的那一层,HARD-CODE,在编译policy代码时决定具体加载哪些module;(3)一个图形化的编程工具用于编写policy,这个GUI可以没有,但工具一定要有。很好,这个架构很明晰!尤其是module的引入以及编译时对module的选择。哦,差点忘了说为什么管理或称为policy脚本还需要编译,因为在WSN网络上直接传输脚本string……数据量比较大,先编译成字节码以减少网络开销,也方便解释器进行解释(有一部分工作交给编译器做就行了)。其中policy system 与module library 要运行在节点之上,需要特别优化与设计。

先扯扯Finger2 policy system,整个系统的关键就在于这里。

image

图-1 Finger2 架构

图-1展现了Finger2 的基本架构,其中粗的实黑线代表执行流程,嗯,有两个起始点;细实黑线代表不同模块间的接口;虚线代表数据的引用。Eg:有一个来自网络的请求进入节点,首先通过认证模块(嗯,应该只是记录权限等级);而后进入事件管理模块,事件管理模块去查询对应的policies库中有无请求调用的policy,如果有,将其放入VM中执行;执行时先根据当前任务所具有的权限等级(前面已经记录)判别每一步动作是否可以被执行,如可,调用module中的functions执行之。

很明显的一点Finger2 中包含一个VM,涉及到VM肯定就有相应的编程语言,当然在这里可以称之为策略式语言……当然不能很复杂……主要原因是我们能力有限,复杂了没法整……当然还因为解释器运行在node中,语言复杂了,解释器相应的可能会变得复杂,node可承受不起。所以要实现这么一个系统,研究编译器与解释器和程序设计语言肯定是少不了了,不过没关系,有的是参考。ponder2就是一个现成的,如果觉得太难,TinyOS的NESCC也可以提供素材,隐约记得Levis也写过一个运行在节点上的解释器(P. Levis and D. Culler. Mate: A tiny virtual machine for sensor networks. ACM SIGARCH Computer Architecture News, 30(5):95, 2002.),不知道Finger2 开源没……

再注意到“Auth Manager”,通常来说所有的远程动作都应该经过此模块,嗯,会影响效率吗?关键要看怎么实现。现在这部分还不是主要内容(在实际使用中很重要),先Pass过去,但要预留好足够的拓展性。

最后谈谈policy的分发问题。通过上面的论述可以看出policy是依靠于module中的Functions来执行实际的内容的,policy是可以动态装载运行的,但module是HARD-CODE(用c或其他程序设计语言编写)在节点之中的,这也就决定了一个节点没法运行所有的policy,其可扮演的role是有限制的。在编译节点对应的policy时就应该做这样的可行性检测,不要到运行时才发现其不能执行相应的policy,浪费传输的能量与带宽!那policy应该存放于节点的什么地方呢?RAM?ROM?其实都可以,编译后policy的大小应该不大,但如果一个节点中有太多的policy则放置于ROM中是合理的选择,但这样做会增加存储与调用时的时间开销,所以Keep it simple,一个节点别做太多事……

具体细节没法讲太多,可以看看原文,哦,最后看一个policy的例子。前两个policy均是由一些条件触发的on something;而第三个是Authorise policy,有subject与target,当发送者与目标满足条件时触发此policy。

def ECG request
    on gui.RequestUpdate(patient, type)
    if network.IsAvail(patient) and type is ECG
    do patient.policy.Install(ECG update)
On request from the nurse of an ECG update for a
patient, install mission ‘ECG update’ on the patient’s
endpoint.

def ECG update
    on sensor.Reading(type, value)
    if type is ECG
    do network.Send(nurse, value, timer.Now())
On receiving of an ECG reading transmit it over the
network to the nurse along with a local timestamp.

def allow nurse policy install+
    subject nurse
    target patient
    if power.Level() > 20 and nurse.type is staff nurse
    action policy.Install
Authorise access of ‘policy.Install()’ to a staff nurse
given that the local power level is above 20%.

下面就是module library的设计。

不得不说这一部分是系统中最难设计的,如同C库和STL的设计一样。哪些是必须提供的,哪些是可选的……嗯,我们要研究(老张的口气)一下……且看一下Starfish中定义了哪些在Fundamental modules中。

既然称之为WSN,那么sensor module自然不能少,但现实中sensor那么多怎么样做到拓展性更好呢?新宝的研究提供了另一种可能性,不过这里我们不做过多的介入。Ok,Sensor Module要提供一组通用接口以便每种传感器都能使用,嗯,Starfish中有两个:“Sense”“Get”。Sense 的功能是周期性的采集传感器信息;Get 是异步的(立即)采集传感器信息。具体的实现方式则留给Module 设计者来解决了,嗯,看两个实际policy 的例子。

def Initialize
    on boot.Done()
    if sensor.IsOk(temp)
    do sensor.Sense(temp, 250),
        buffer.Create(temp, 50)
On boot-up set the temperature sensor to read
every 250ms and create a buffer of size 50 for readings.

def StoreTemperature
    on sensor.Reading(type, value)
    if type is temp
    do buffer.Add(type, value)
On receiving an event from the temperature sensor
and store it in the buffer.

def SendAvgTemp
    on buffer.Full(type)
    if type is temp and network.IsAvail(tempGtor)
    do network.Send(tempGtor, tempUpdate,
        feature.Avg(buffer.Get(type)))
When the buffer is full, send the average temperature
over the network to node ‘tempGtor’.

可以看见policy中的sensor、buffer、network以及feature就是一个个的module,嗯,不错……

Buffer module,不错,Starfish 也将buffer 作为一个module来实现了。这个还真的要有,其他module肯定有使用buffer的需求的,比如求平均,取最小值等操作。但我们的设计中可不可以不局限于buffer,想想STL中的容器还有作用在其上的操作……嗯,有搞头。以此推广开来,实现一个简化版本的STL也未尝不可…… >_<||| 又扯远了……

Arithmetic Association Logical operator.这个加上上面的Buffer不就是简化版的STL吗……

Timers,这个也是必须有的。你比如说周期性操作,延时操作都需要timer的,至于绝对时间的确定,嗯,只能使用网络进行同步。Starfish Module Library(SML)中timers提供的功能有:Periodic 和OneShot。

当然,Network Module 怎么能少呢?将底层与操作系统直接交互的部分作封装,只关心应用层的内容!既然我们的研究基于IP,单播、广播、组播都是必须的咯;当然接收端要有Receive event可以触发,使用观察者模式注册侦听;检测连通性的函数也必须要能提供。

当然为了测试需要,Serial Module也是必须的,基本的两个函数“Send”“Receive”(异步Event形式)就足够了。

PS:

为什么系统中有Network、timer等等API,还需要重新加一层包装?嗯,要知道,在Policy系统运行的Action只能调用Module Library中的function,不将系统中的功能包一层新皮,怎么用呢?难道再做一个Native接口?这就很不合理了,Policy与Native function的接口就是Module!

Module Library 怎么管理?嗯,确实,当一个policy 调用一个module 的时候我们怎不能花大把时间去寻找这个module的位置吧……原文中没说,那该肿么办呢?OSGI中是怎么组织bundle的?嗯……明白了。

好了,这么多Policy管理起来也是一个问题。

嗯,我脑中突然闪现一个名词“OSGI”,很好的开源参考资料吗!原来我做的这么多事都是有意义的,都是融汇贯通的,必须的!Starfish中的Policy 管理与OSGI很相像,Install、Remove、Enable和Disable四种基本操作。

为了管理方便,Starfish 又引入missions 的概念,将一组policies 组合成一个mission,使用与之对应的mission管理方法。

嗯,关于Module 的拓展与编写Module。

开发Module 的人员应该只关注三个接口:EventSourceI(可以接受一大批的观察者),PredicateI(同步执行操作Block 直到执行完毕),ActionI(异步执行操作立即返回)。当然,名字可以不同,上面只是接口的种类……Module中可以存在上述三种接口。应该提供简便的方法来辅助Module 编程,嗯,最好还是使用纯粹的C形式,使用Makefile加上通用架构文件来简化编程的复杂度,就像Linux 中开发驱动程序一样。

最后就是Policy 编程工具了。

嗯,就像前文中所说的Policy 是交由网络管理员来制定的,总不能让所有网络管理员都学习嵌入式编程吧……于是乎提供一个简便的Policy 设计工具非常必要。Starfish提供的是一个带GUI的设计工具,我们先不用GUI了,先把Policy 编译器设计出来再说吧……

引入三个概念:“Missions”、“Roles”和“Configurations”。

先对这三个概念进行一下说明。

首先是Missions 与Roles。missions 是一组policies 的集合,包括policies 本身和它们之间的关系和执行顺序,但policies之间的关系不用中间件去操心,这部分在编译期间就已经处理完毕。Roles 是实现Missions 与policies 和节点解耦的关键概念,Starfish 中将missions 和 policies与Roles 进行对应(感觉可以是多对多)而不是与实际节点,这样每个节点所扮演的角色就可以转换,也可以扮演多重角色(当然肯定有些角色之间是互斥的关系)。当然需要注意的是由于每个节点在烧录时载入的modules 是有限与固定的,是故决定了每个节点所能扮演的角色也是有限的,其所能加载的Missions 和policies 也是有限的。最后,当节点决定扮演一个Role 时就会激活一些Missions 和 Policies;其卸去一个角色的同时,也会使相应的一些Mission 和Policies 失效,这里有一个问题,如果节点同时扮演几个角色,而这几个角色之间的Missions 或 Policies 有重叠的部分呢?这时就不可以在节点褪去一个角色的同时是其所有对应的Missions 和 Policies失效,只能反激活其独有的部分!

Configurations,很简单,就是节点初始化时的默认配置。其中含有节点需要载入的所有Modules,节点初始时所扮演与要激活的角色等等。

嗯,根据上述概念,下面总结一下编程工具应该提供什么样的功能。

Policies 的编译工具自然不用多说,必须有,嗯,当然还有对应的语法说明。Missions 与Roles 的编写应该简单的多,就是组合和关联,以及处理一些依赖项,也许不需要发明特有的语言,使用已有的工具就行 ^_^

关于Modules,有些Module 应该是平台独有的,比如说有些特殊的传感器只能用于特定的平台之上;而有些Module是通用的,这些特殊的限制应当在编写Module 时就加以说明。加入一个Manifest??嗯,也许policies也可以使用标准XML的形式编写……可行与否要研究一下!当然,Modules 必须使用Native Programming Language 编写,即使用C 或是NESCC等等,使用与Linux 驱动程序相似的方式进行编译应该可行。

最后的最后,相关架构和工作可以参看Starfish 和 中科院WSN管理论文后面的相关论述,嗯,See you.

参考资料:

[1] Themistoklis Bourdenas, Morris Sloman. Starfish -- Policy driven self-management in wireless sensor networks. 2010 ACM 978-1-60558-971-8/10/05

你可能感兴趣的:(Starfish -- 基于策略的WSN网络自治系统)