Promela BCL-6 A Protocol

/*
*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
:: skip
fi
od
}


proctypereceiver2media()
{
byteseq;
do
:: revts ? ACK , seq ->
if
:: sevts ! ACK , seq
:: skip
fi
od
}







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
:: else
fi
:: (head_seq > tail_seq) -> /* 非递增情景 */
if
:: (s < head_seq && s > tail_seq) ->
gotoendofack
:: else
fi
:: else
fi;

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 ) % WIN
fi
fi

od

}


init
{
atomic{
runsender(
0 );
runsender2media();
runreceiver(
1 );
runreceiver2media();
}

}

你可能感兴趣的:(protocol)