/**PROMELAValidationModel*协议层验证**验证BCL可靠性协议Aversion5.0**Yuhuang*2007-7-26*//**本版本特点:采用集合点来通信,允许ACK、DATA丢包,实现了队列自动重发。*加入了对传输介质的模拟。介质可以丢包,导致包失序。**未完全模拟的问题:ACK、DATA失序问题*//**************数据结构定义*************//*序号范围定义*/#defineWIN9/*发送队列大小定义*/#defineQSIZE4/*消息类型定义*/mtype={ACK,DATA}/**{ACK,s_seqno}*/chansevts=[0]of{mtype,byte};chanrevts=[0]of{mtype,byte};/**{DATA,r_seqno}*数据队列*/chansdata=[0]of{mtype,byte};chanrdata=[0]of{mtype,byte};/*发送记录队列*//*当ACK发生的时候,ACK(含)之前的内容都被清除*/bytehead_seq;bytetail_seq;bytecur_seq;/*#defineinc(x)(x=(x+1)%WIN)*/proctypesender2media(){byteseq;do::sdata?DATA,seq->if::rdata!DATA,seq::skipfiod}proctypereceiver2media(){byteseq;do::revts?ACK,seq->if::sevts!ACK,seq::skipfiod}proctypesender(byteid){bytes;head_seq=0;tail_seq=0;cur_seq=0;do::(tail_seq+WIN-head_seq+1)%WIN!=QSIZE->/*队列不为满,允许发送*/if::sdata!DATA,cur_seq/*normalsendaction*/fi;progress_2:cur_seq=(cur_seq+1)%WIN;tail_seq=(tail_seq+1)%WIN;;/*更新tail,head保持不变*/::sevts?ACK,s->/*进行ACK失序处理*//*若s不在当前的head_seq~tail_seq范围内,则简单忽略之*/if::(head_seq<tail_seq)->/*顺序递增情景*/if::(s>tail_seq||s<head_seq)->gotoendofack::elsefi::(head_seq>tail_seq)->/*非递增情景*/if::(s<head_seq&&s>tail_seq)->gotoendofack::elsefi::elsefi;assert(s<WIN);head_seq=(s+1)%WIN;/*根据ACK更新head_seq,暗含了累积更新*/cur_seq=head_seq;endofack:skip::((cur_seq!=tail_seq)&&(tail_seq-head_seq)!=0)->/*队列不为空,允许发送.此情景配合timeout时重发使用*//*第一个判断是为了防止发送不存在内容*/if::sdata!DATA,cur_seq/*normalsendaction*/fi;cur_seq=(cur_seq+1)%WIN;::timeout->/*超时*//*更新指针,准备重发队列*/cur_seq=head_seq;/*尝试重发队列*/if::sdata!DATA,cur_seq/*normalsendaction*/fi;cur_seq=(cur_seq+1)%WIN;/*发送了一个包,更新cur_seq*//*这里不用更新tail_seq,因为这个值只在有新的包加入到队列的时候才更新*/od}proctypereceiver(byteid){byteexpected_seqno;bytes;expected_seqno=0;do::rdata?DATA,s->if::(s!=expected_seqno)->/*非期望数据包*/if::revts!ACK,(expected_seqno+WIN-1)%WIN/*someackswaslost,ackagain!*/fi::(s==expected_seqno)->/*期望数据包*/if::revts!ACK,expected_seqno->/*ack*/expected_seqno=(expected_seqno+1)%WINfifiod}init{atomic{runsender(0);runsender2media();runreceiver(1);runreceiver2media();}}