【案例描述】:由于C语言中位与比求模效率高,因而系统设计时,对于模128的地方都改为与127,系统定义的宏为#define MOD128 127和#define W_MOD 127(定义的宏的名字易引起误解),但实际程序中还是采取求模,从而引起发送窗口欲重发的和实际重发的不一致,最终导致链路复位此类严重问题,曾在定位此问题时花了不少时间。
【处理过程】:处理过程如下:
#define MOD128 127 //队列长128,当队头到128时,上其返回。
#define W_MOD 127 //发送窗口队列,意义同上。
在函数L2_TO_L1()中,有如下语句:
linkstate_ptr->SendWin.head = (head + 1) % W_MOD ;
这里当head=126时,SendWin.head = 0,这将造成发送窗口指针和队列窗口指针错位,造成链路复位;
另外,在重发函数void INVOKE_RETRANSMISSION(_US logic_link,_US n_r)中,有如下语句:
retran_num = (LinkState[logic_link].Vs + MOD128 - (_UC)n_r) % MOD128 ;
w_head = (LinkState[logic_link].SendWin.head + W_MOD - retran_num) % W_MOD ;
第一个语句求欲重发的消息包个数,第二个语句求重发的起始位置,当Vs小于n_r时,将造成实际重发数小于欲重发数,同时造成实际起始重发位置和欲重发起始位置错开,从而引起链路复位。上面三个语句应该做如下改动:
linkstate_ptr->SendWin.head = (head + 1) & W_MOD ;
retran_num = (LinkState[logic_link].Vs + MOD128 + 1 - (_UC)n_r) & MOD128 ;
w_head = (LinkState[logic_link].SendWin.head + W_MOD + 1 - retran_num) & W_MOD ;