-
Notifications
You must be signed in to change notification settings - Fork 0
/
sliding_window.cpp
166 lines (140 loc) · 4.22 KB
/
sliding_window.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "trans_protocols.h"
int StopNWait::sendMsg (MSG_TYPE msg, ACK_TYPE *slast) {
ackbuff ack;
msgbuff msg_temp;
ACK_TYPE rnext = !(*slast);
struct msqid_ds msg_info;
#ifdef MANUAL_ERROR
float prob_error;
#endif
signal(SIGALRM, alarm_dummy);
ack.mtype = 1;
msg_temp.mtype = 1;
// append the slast
msg_temp.msg = msg << SLAST_SIZE;
msg_temp.msg += *slast;
// apply theoretical error and CRC
msg_temp.msg = msg_temp.msg << CRC_SIZE;
msg_temp.msg += crc(msg_temp.msg);
#ifdef AUTO_ERROR
msg_temp.msg = apply_error(msg_temp.msg, PROB_ERROR);
#endif
#ifdef MANUAL_ERROR
cout << "Error chance (0-1): ";
cin >> prob_error;
msg_temp.msg = apply_error(msg_temp.msg, prob_error);
#endif
// send the package to the transmition mean buffer
cout << "Sending message: " << msg_temp.msg << endl;
if (msgsnd(inputChannelId, &msg_temp, sizeof(msgbuff), 0) < 0) {
cout << "Error sending package through the msg queue: " << strerror(errno) << endl;
exit(1);
}
// clean the ack buffer, if filled with old ack's
if (timeout > 0) {
msgctl(outputChannelId, IPC_STAT, &msg_info);
if (msg_info.msg_qnum > 0) {
cout << "ack flushed: " << ack.ack << " - number or msgs: " << msg_info.msg_qnum << endl;
if (msgrcv(outputChannelId, &ack, sizeof(ackbuff), 0, 0) < 0) {
cout << "Message Queue error: " << strerror(errno) << endl;
exit(1);
}
}
timeout = 0;
}
// wait for the ack or the timeout
cout << "Waiting for the acknowledge" << endl;
alarm(TIMEOUT);
if (msgrcv(outputChannelId, &ack, sizeof(ackbuff), 0, 0) < 0)
if (errno != EINTR){
cout << "Message Queue error: " << strerror(errno) << endl;
exit(1);
}
cout << "ack received: " << ack.ack << endl;
// treat the result of an ack
if (alarm(0) > 0) {
// crc on the ack
if (crc(ack.ack) != 0)
cout << "Acknowledge failed on CRC check" << endl;
// extract slast from the ack and check it
else if (EXTRACT_RNEXT(ack.ack) != rnext)
cout << "Received wrong acknowledge - expected " << rnext << " but instead " << (EXTRACT_RNEXT(ack.ack)) << endl;
else {
cout << "Received correct acknowledge" << endl;
// update slast
*slast = rnext;
return true;
}
}
// treat the result of a timeout
else {
cout << "Timeout!" << endl;
timeout++;
}
return false;
}
int StopNWait::recvMsg (MSG_TYPE *msg, ACK_TYPE *rnext) {
ackbuff ack;
msgbuff msg_temp;
#ifdef MANUAL_ERROR
float prob_error;
#endif
ack.mtype = 1;
msg_temp.mtype = 1;
// receive message from the transmition mean buffer
cout << "Waiting message..."<< endl;
if (msgrcv(inputChannelId, &msg_temp, sizeof(msgbuff), 0, 0) < 0) {
cout << "Error sending package through the msg queue: " << strerror(errno) << endl;
exit(1);
}
cout << "Received message: " << msg_temp.msg << endl
<< "crc: " << crc(msg_temp.msg) << endl;
// CRC check
if (crc(msg_temp.msg) != 0) {
// discart package
cout << "Error during transmition...Exiting..." << endl;
}
// check the slast
else if (*rnext == EXTRACT_SLAST(msg_temp.msg)) {
// if ok send updated rnext
cout << "Message received - Sending acknowledge" << endl;
*rnext = !(*rnext);
ack.ack = *rnext;
ack.ack <<= CRC_SIZE;
ack.ack += crc(ack.ack);
#ifdef AUTO_ERROR
ack.ack = apply_error(ack.ack, PROB_ERROR);
#endif
#ifdef MANUAL_ERROR
cout << "Error chance (0-1): ";
cin >> prob_error;
ack.ack = apply_error(ack.ack, prob_error);
#endif
if (msgsnd(outputChannelId, &ack, sizeof(ackbuff), 0) < 0) {
cout << "Error sending package through the msg queue: " << strerror(errno) << endl;
exit(1);
}
*msg = EXTRACT_MSG(msg_temp.msg);
return true;
}
// otherwise send actual rnext
else {
cout << "Message received isn't the requested - expected " << *rnext << " but received " << (EXTRACT_SLAST(msg_temp.msg)) << " - Sending acknowledge" << endl;
ack.ack = *rnext;
ack.ack <<= CRC_SIZE;
ack.ack += crc(ack.ack);
#ifdef AUTO_ERROR
ack.ack = apply_error(ack.ack, PROB_ERROR);
#endif
#ifdef MANUAL_ERROR
cout << "Error chance (0-1): ";
cin >> prob_error;
ack.ack = apply_error(ack.ack, prob_error);
#endif
if (msgsnd(outputChannelId, &ack, sizeof(MSG_TYPE), 0) < 0) {
cout << "Error sending package through the msg queue: " << strerror(errno) << endl;
exit(1);
}
}
return false;
}