1+ #include <stdbool.h>
2+ #include <stdio.h>
3+ #include <string.h>
4+
5+ #include "../protocol.h"
6+ #include "../datalink.h"
7+
8+ typedef unsigned char seq_nr ;
9+ typedef unsigned char frame_kind ;
10+
11+ struct FRAME {
12+ unsigned char kind ; /* FRAME_DATA */
13+ unsigned char ack ;
14+ unsigned char seq ;
15+ unsigned char data [PKT_LEN ];
16+ unsigned int padding ;
17+ };
18+
19+ struct BUFFER {
20+ unsigned char data [PKT_LEN ];
21+ size_t len ;
22+ };
23+
24+ /* 发送窗口相关变量 */
25+ static struct BUFFER out_buf [NR_BUFS ]; /* 发送方缓存区 */
26+ static unsigned char nbuffered = 0 ; /* 发送缓存区被使用个数 */
27+
28+ /* 接收窗口相关变量 */
29+ static struct BUFFER in_buf [NR_BUFS ]; /* 接收方缓存区 */
30+ static bool arrived [NR_BUFS ]; /* 接收方缓存区状态 */
31+
32+ static seq_nr i = 0 ; /* 缓存区索引 */
33+ static int phl_ready = 0 ;
34+ static bool no_nak = true;
35+
36+ // 判断是否处于在窗口中
37+ static bool between (seq_nr a , seq_nr b , seq_nr c )
38+ {
39+ return a <= b && b < c || c < a && a <= b || b < c && c < a ;
40+ }
41+
42+ // 添加校验段,发送DATA帧到物理层
43+ static void put_frame (unsigned char * frame , int len )
44+ {
45+ * (unsigned int * )(frame + len ) = crc32 (frame , len );
46+ send_frame (frame , len + 4 );
47+ phl_ready = 0 ;
48+ }
49+
50+ // 根据不同类型构建帧、发送帧、处理计时器
51+ static void send_frame_datalink (frame_kind fk , seq_nr frame_nr , seq_nr frame_expected )
52+ {
53+ struct FRAME s ;
54+ s .kind = fk ;
55+ s .ack = (frame_expected + MAX_SEQ ) % (MAX_SEQ + 1 );
56+ if (fk == FRAME_DATA )
57+ {
58+ s .seq = frame_nr ;
59+ memcpy (s .data , out_buf [frame_nr % NR_BUFS ].data , out_buf [frame_nr % NR_BUFS ].len );
60+ dbg_frame ("Send DATA %d %d, ID %d\n" , s .seq , s .ack , * (short * )s .data );
61+ put_frame ((unsigned char * )& s , 3 + out_buf [frame_nr % NR_BUFS ].len );
62+ start_timer (frame_nr % NR_BUFS , DATA_TIMER );
63+ }
64+ else
65+ {
66+ if (fk == FRAME_NAK )
67+ {
68+ s .ack = frame_expected ;
69+ dbg_frame ("Send NAK %d\n" , frame_expected );
70+ }
71+ else
72+ dbg_frame ("Send ACK %d\n" , s .ack );
73+ send_frame ((unsigned char * )& s , 3 );
74+ }
75+ stop_ack_timer ();
76+ }
77+
78+ int main (int argc , char * * argv )
79+ {
80+ static seq_nr ack_expected = 0 ; /* 发送窗口下界 */
81+ static seq_nr frame_nr = 0 ; /* next_frame_to_send,即发送窗口上界 + 1 */
82+ static seq_nr frame_expected = 0 ; /* 接收窗口的下界 */
83+ static seq_nr too_far = NR_BUFS ; /* 接收窗口的上界 + 1 */
84+
85+ int event , arg ;
86+ struct FRAME f ;
87+ int len = 0 ;
88+
89+ /* 初始化接收窗口状态,并没有被缓存的帧 */
90+ for (i = 0 ; i < NR_BUFS ; i ++ ) {
91+ arrived [i ] = false;
92+ }
93+
94+ protocol_init (argc , argv );
95+ lprintf ("Datalink using Selective-Repeat protocol designed by Zhang Keming, "
96+ "build: " __DATE__ " " __TIME__ "\n" );
97+
98+ disable_network_layer ();
99+
100+ while (true)
101+ {
102+ event = wait_for_event (& arg );
103+
104+ switch (event )
105+ {
106+ case NETWORK_LAYER_READY : // 网络层就绪
107+ nbuffered ++ ;
108+ out_buf [frame_nr % NR_BUFS ].len = get_packet (out_buf [frame_nr % NR_BUFS ].data );
109+ send_frame_datalink (FRAME_DATA , frame_nr , frame_expected ); // 发送DATA帧
110+ inc (frame_nr );
111+ break ;
112+
113+ case PHYSICAL_LAYER_READY :
114+ phl_ready = 1 ;
115+ break ;
116+
117+ case FRAME_RECEIVED :
118+ len = recv_frame ((unsigned char * )& f , sizeof f );
119+ if (len < 5 && len != 3 )
120+ break ;
121+ if (len >= 5 && crc32 ((unsigned char * )& f , len ) != 0 ) // 校验错误
122+ {
123+ dbg_event ("**** Receiver Error, Bad CRC Checksum ****\n" );
124+ send_frame_datalink (FRAME_NAK , 0 , f .seq );
125+ break ;
126+ }
127+
128+ if (f .kind == FRAME_ACK )
129+ dbg_frame ("Recv ACK %d\n" , f .ack );
130+
131+ if (f .kind == FRAME_DATA )
132+ {
133+ dbg_frame ("Recv DATA %d %d, ID %d\n" , f .seq , f .ack , * (short * )f .data );
134+ start_ack_timer (ACK_TIMER );
135+ if (between (frame_expected , f .seq , too_far ) && !arrived [f .seq % NR_BUFS ])
136+ {
137+ arrived [f .seq % NR_BUFS ] = true;
138+ memcpy (in_buf [f .seq % NR_BUFS ].data , f .data , len - 7 );
139+ in_buf [f .seq % NR_BUFS ].len = len - 7 ;
140+ while (arrived [frame_expected % NR_BUFS ]) // 将接收缓冲区中连续的已收到的帧发送到网络层
141+ {
142+ put_packet (in_buf [frame_expected % NR_BUFS ].data , in_buf [frame_expected % NR_BUFS ].len );
143+ arrived [frame_expected % NR_BUFS ] = false;
144+ inc (frame_expected );
145+ inc (too_far );
146+ start_ack_timer (ACK_TIMER );
147+ }
148+ }
149+ }
150+
151+ if (f .kind == FRAME_NAK && between (ack_expected , f .ack , frame_nr )) // 发送特定的NAK帧
152+ {
153+ dbg_frame ("Recv NAK %d\n" , f .ack );
154+ send_frame_datalink (FRAME_DATA , f .ack , frame_expected );
155+ break ;
156+ }
157+
158+ while (between (ack_expected , f .ack , frame_nr )) // 累计确认
159+ {
160+ nbuffered -- ;
161+ stop_timer (ack_expected % NR_BUFS );
162+ inc (ack_expected );
163+ }
164+ break ;
165+
166+ case DATA_TIMEOUT :
167+ dbg_event ("---- DATA %d timeout ----\n" , arg );
168+ if (!between (ack_expected , arg , frame_nr )) // 计时器中的序号只有一半,要将序号转化到窗口区间内
169+ arg += NR_BUFS ;
170+ send_frame_datalink (FRAME_DATA , arg , frame_expected );
171+ break ;
172+
173+ case ACK_TIMEOUT :
174+ dbg_event ("---- ACK %d timeout ----\n" , frame_expected );
175+ send_frame_datalink (FRAME_ACK , 0 , frame_expected );
176+ break ;
177+ }
178+
179+ if (nbuffered < NR_BUFS && phl_ready )
180+ enable_network_layer ();
181+ else
182+ disable_network_layer ();
183+ }
184+ }
0 commit comments