-
Notifications
You must be signed in to change notification settings - Fork 1
/
receiver.py
128 lines (102 loc) · 3.92 KB
/
receiver.py
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
"""
This module contains various functions related to the receiver
"""
from utils import get_bin, list2int, int2list
class Receiver():
"""
This class forms the basic structure of the receiver object
"""
def __init__(self, num_messages):
"""
It intializes the receiver's state as empty (no message has been received)
Parameters
----------
num_messages : `int`
Number of messages the receiver is expected to receive
"""
self.received_messages_list = [False] * num_messages
self.messages_list = [[]] * num_messages
self.received_packet_list = [False] * num_messages
def update_packet_reception(self, packet_number, received):
"""
Updates the reception of the `packet_number` packet in the receiver's
memory
Parameters
----------
packet_number : `int`
The packet number whose is reception state is being stored
received : `bool`
whether the packet was received or not
"""
self.received_packet_list[packet_number] = received
def receive_packet(self, packet_header, packet, size):
"""
Receive a packet and split it into its constituent symbols
Parameters
----------
packet_header : `list` or `int`
stores information about the constituent symbols whether coded or not and with
what symbols
packet : `list`
actual contents of the packet
size : `int`
Number of symbols in the packet
"""
for packet_number, message in zip(packet_header, packet):
if type(packet_number) is list:
self.decode(packet_number, message)
else:
self.messages_list[packet_number] = message
self.received_messages_list[packet_number] = True
def decode(self, coding_list, coded_message):
"""
Decodes a coded symbol
Parameters
----------
coding_list : `list`
List of symbols which has been coded together
coded_message : `list`
The actual message
"""
ans = 0
for idx in coding_list:
ans += self.received_messages_list[idx]
if ans == len(coding_list):
# print('All packets are already present')
pass
elif ans < len(coding_list) - 1:
# print('Decoding cannot be done as more than one messages are missing')
pass
else:
coded_message = list2int(coded_message)
for idx in coding_list:
if self.received_messages_list[idx]:
coded_message = coded_message ^ list2int(self.messages_list[idx])
else:
decoded_idx = idx
self.messages_list[decoded_idx] = int2list(coded_message, 8)
self.received_messages_list[decoded_idx] = True
def send_feedback(self, packet_number, delay_tolerance):
"""
Generate feedback for the sender
Parameters
----------
packet_number : `int`
The current packet number received
delay_tolerance : `int`
The delay tolerance
Returns
-------
`list`
The feedback for the sender
"""
# Interval of interest starting position
lower = max(0, packet_number - delay_tolerance + 1)
try:
index = packet_number - self.received_messages_list.index(False, lower, packet_number+1)
num_unreceived = (packet_number + 1 - lower) - sum(self.received_messages_list[lower:packet_number+1])
except ValueError as _:
index = 0
num_unreceived = 0
feedback = str(int(self.received_messages_list[packet_number])) + get_bin(index, 8) + get_bin(num_unreceived, 8)
return feedback