浅介TTCN-3中语法特性对通信协

来源:互联网 发布:怎么查淘宝的账户余额 编辑:程序博客网 时间:2024/04/30 13:35

AuthorXingzai LvDate2007-10-13

TTCN-3ETSI指定的一个强大的黑盒测试标准,其标准的内容包括核心语言,整体架构和与其他各个模块的接口。由于项目进展需要,上周我对TTCN-3进行了一些调研。由于时间又比较短,且缺乏计算机专业方面的知识,因此TTCN-3标准对我来说比较难以理解,想必计算机专业出身的人读通信协议的感受应该和我的感觉类似。以下尽我所能对TTCN-3语法中对通信协议的支持展开一些浅薄的讨论。以下蓝色粗体,如type,为TTCN-3中的关键字。

1.List & Range

TTCN-3中,定义一个类型的时候(如C中的typedef),不仅可以把内置类型定义为自己的类型,同时还可以给出该类型的取值范围,取值范围可以是一个List,也可以给定一个Range。比如:

type integerMyIntegerRange (0 .. 255);

type charstringMyStringList ("abcd", "rgy", "xyz");

上式中分别定义了一个新的整数类型MyIntegerRange,其取值范围为0255定义了一个新的字符串类型MyStringList,其取值范围为"abcd", "rgy", "xyz"三个字符串之一。即使都是整数,但是取值范围不一致,也会被TTCN-3认为是不兼容的类型。

尽管很多语言都支持这个特性,但该功能不失实用。我们肯定还记得,在通信协议中,很多属性的取值都是属于一定范围的整数,浮点数,或者是一些离散的整数值。比如窗口的大小,FFT的点数,等等。以WiMAXARQ_BLOCK_SIZE为例,该值可取:16, 32, 64, 128, 256, 512, 1024。因此我们可做如下定义:

type integerWIARQBlockSizeType (16, 32, 64, 128, 256, 512, 1024);

WIARQBlockSizeTye arqBlockSize

我们无须担心代码里的这个arqBlockSize被赋上一个非法的值,也无须另外一个不同类型的整数被赋给了arqBlockSizeTTCN-3会自动为我们保证正确性。

2.Record & Set

RecordSet类似与C语言中的结构体,不同的是,Record中各个属性是有严格顺序关系,而set中各个属性则没有顺序的关系。更为强大的是,RecordSet都可以提供optional的属性,即下面的某个属性可以是无效的。如

typerecord MyRecordType

{

integerfield1,

MyOtherRecordType field2optional,

charstringfield3

}

field2是一个可以忽略,即可以不在结构体中出现的属性。这是否让你想起了什么呢?是的,WiMAX中万恶的可有可无的TLV。利用set结构,和optional关键字,可以方便的从逻辑上简洁地描述这种灵活的结构,不再需要一大堆的present。一条空口消息无非包括固定的有序部分和可选的变化部分,一个record结构套上一个set结构即可以完美表达。

3.Template

TemplateTTCN-3提供的强大的功能,分为消息模板和函数模板。如果你不幸学过C++,可能会把这里的Template概念和C++中的Template概念搞混,事实上,二者是十分不同的东西。TTCN-3中的Template实际上是一个特定值的集合,你可以用Template来规定一组传输的数据,或是测试接收的值的集合是否与Template中的规定匹配。

由于Template比较复杂,在此不在举例说明,有兴趣的可以去参阅相关文档。我想说明的是,Template提供一个最有用的功能的,它使函数可以在传入某些参数的情况下才被调用,或者是从接收到的消息中过滤出符合特殊要求的消息。由于它是在底层语法级别上支持这一功能,Template可以和任何内置或自定义的类型联用,因而极大简化了程序。比如上一点中自定义的消息类型就可以和Template连用,构成消息模板。这样TTCN-3会自动检测消息是否和模板中指明的域是否匹配,并在匹配时才调用相关操作(是的,QL,这就是MASK)。对任何通信协议的一致性测试,这都是个极为重要的功能。

4Altsteps

Altsteps又是一个即为强大的功能。你可以将它等同与C中的switch-case语句,但Altsteps比后者强大得多,而且是动态的。有例如下:

alt{

[ ] L1.receive {// Boolean guard/expression

setverdict(pass);

}

[ ] L2.receive {// Boolean guard/expression

setverdict(inconc);

}

}

在进入alt语句块前,TTCN-3会进行一次Snapshot,“照”下当前系统内的状态,然后依据这个状态触发对应的alt branch。如上面的例子。如果port L2中有消息,可以被接收,就会运行第二条branch{}的语句。这东东用来写状态机是十分合适的,特别是配合Template,可以避免你设无穷多个状态变量。alt语句中,你可以如下写:

MyPort.call(MyProc:{ -, MyVar2}) {// in-line signature template for the call of MyProc

[] MyPort.getreply(MyProc:{?, ?}) { }

}

上面指出了我们调用了一个MyProcRPC,并且在MyPort这个Port等待他的答复。如果用C语言实现,我们很可能设置一个变量来记录我们发起过这个调用并在等待回应,并且检查收到的每一条消息,看他是否是来自MyProcReply;这样的调用一多,状态变量必然很多,难以避免地会出现一大堆层层嵌套的switch-case语句。而Altsteps可以将逻辑相关的语句有效地捏合在一起,有利于阅读和维护。

TTCN-3中还有好些好玩的东西,比如anytyperun onwith等等关键字,对port的操作,及基于procedure的通信,都是很有意思的语法特性,限于体力,不做介绍。总之,TTCN-3语言本身是种比较抽象和高级的语言,屏蔽了很多琐碎的细节,coder可以集中注意在逻辑和协议本身。可惜的是,没有找到TTCN-3的开源实现,商业的TTCN-3可能会比较昂贵。由于TTCN-3比较复杂,比如以上特性,基本上都需要利用多线程和通信特性,系统可移植性也是个问题,也许用Java实现是一个比较好的选择。无论如何,对于复杂的分布式开发系统,要部署TTCN-3,其至少在接口方面的开源是必须的,而且需要很大一番努力将其整合进现有系统。

1 0