prrt.pyx 7.41 KB
Newer Older
Andreas Schmidt's avatar
Andreas Schmidt committed
1
from libc.stdint cimport uint32_t, uint16_t, uint8_t, int32_t
Andreas Schmidt's avatar
Andreas Schmidt committed
2
from libc.stdlib cimport malloc, free
3
from posix.time cimport timespec
rna's avatar
rna committed
4
cimport cython
Andreas Schmidt's avatar
Andreas Schmidt committed
5

6
7
cimport cprrt

8
cdef extern from "proto/applicationConstraints.c":
9
10
    pass

11
cdef extern from "proto/stores/dataPacketStore.c":
12
13
    pass

14
cdef extern from "proto/stores/deliveredPacketTable.c":
15
    pass
16

Andreas Schmidt's avatar
Andreas Schmidt committed
17
18
19
20
cdef extern from "proto/stores/receptionTable.c":
    pass

cdef extern from "proto/stores/packetTimeoutTable.c":
21
22
    pass

23
cdef extern from "proto/stores/packetTimeoutTable.c":
24
25
    pass

26
27
28
cdef extern from "proto/stores/inFlightPacketStore.c":
    pass

29
cdef extern from "proto/stores/repairBlockStore.c":
30
31
    pass

32
cdef extern from "proto/stores/packetDeliveryStore.c":
33
34
    pass

Andreas Schmidt's avatar
Andreas Schmidt committed
35
36
37
cdef extern from "proto/types/packetTimeout.c":
    pass

Andreas Schmidt's avatar
Andreas Schmidt committed
38
39
40
cdef extern from "proto/types/lossStatistics.c":
    pass

41
cdef extern from "proto/processes/feedbackReceiver.c":
42
    pass
43

44
cdef extern from "proto/processes/dataReceiver.c":
45
    pass
46

47
cdef extern from "proto/processes/dataTransmitter.c":
48
    pass
49

50
cdef extern from "proto/block.c":
51
    pass
52

53
cdef extern from "proto/clock.c":
54
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
55

56
cdef extern from "proto/channelStateInformation.c":
57
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
58

59
cdef extern from "proto/vdmcode/block_code.c":
60
    pass
61

62
cdef extern from "proto/codingParams.c":
63
    pass
64

65
cdef extern from "proto/receiver.c":
66
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
67

68
cdef extern from "proto/types/packet.c":
69
    pass
70

71
cdef extern from "proto/socket.c":
72
    pass
73
74

cdef extern from "util/bptree.c":
75
    pass
76

77
78
cdef extern from "util/bitmap.c":
    pass
79

80
81
82
cdef extern from "util/common.c":
    pass

83
84
cdef extern from "util/list.c":
    pass
85

Andreas Schmidt's avatar
Andreas Schmidt committed
86
87
88
cdef extern from "util/pipe.c":
    pass

Andreas Schmidt's avatar
Andreas Schmidt committed
89
90
91
cdef extern from "util/mpsc_queue.c":
    pass

rna's avatar
rna committed
92
93
94
95
96
97
98
99
class PrrtCodingConfiguration:
    def __init__(self, n, k, n_cycle):
        # TODO: Validity checks
        # n >= k
        # sum(n_cycle) == n - k
        self.n = n
        self.k = k
        self.n_cycle = n_cycle
100

101
    def __repr__(self):
rna's avatar
rna committed
102
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
103

104
105
106
    def __repr__(self):
        return "({},{},{})".format(self.n, self.k, self.n_cycle)

rna's avatar
rna committed
107
108
109
    #property n_cycle:
    #    def __get__(self):
    #        return list(<uint8_t[:self._c_config.c]> self._c_config.n_cycle)
110

111
112
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket
Andreas Schmidt's avatar
Andreas Schmidt committed
113
    cdef bint isSender
114

115
    def __cinit__(self, port, isSender, target_delay = 1, thread_pinning = False):
116
117
        target_delay_us = target_delay * 1000**2
        self._c_socket = cprrt.PrrtSocket_create(isSender, target_delay_us)
118
119
        if thread_pinning:
            cprrt.PrrtSocket_enable_thread_pinning(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
120
        cprrt.PrrtSocket_bind(self._c_socket, "0.0.0.0", port)
Andreas Schmidt's avatar
Andreas Schmidt committed
121

Andreas Schmidt's avatar
Andreas Schmidt committed
122
        self.isSender = isSender
123

Andreas Schmidt's avatar
Andreas Schmidt committed
124
125
126
127
128
129
130
    property plr:

        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_plr(self._c_socket)

131
132
133
134
135
    property thread_pinning:

        def __get__(self):
            return cprrt.PrrtSocket_uses_thread_pinning(self._c_socket)

136
    property target_delay:
137

138
139
140
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
141
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
142

143
144
145
146
147
148
149
150
151
152
153
    property app_queue_size:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "app_queue_size")

        def __set__(self, value):
            if not self.isSender:
                raise Exception("Not a sender.")
            cprrt.PrrtSocket_set_sock_opt(self._c_socket, "app_queue_size", value)

154
    property rtt:
155
156
157
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
158
            return cprrt.PrrtSocket_get_rtprop(self._c_socket) * 0.000001
159

160
161
162
163
164
165
    property coding_configuration:

        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            cdef cprrt.PrrtCodingParams *params = cprrt.PrrtSocket_get_coding_parameters(self._c_socket)
166
167
168
            result = PrrtCodingConfiguration(params.n, params.k, list(<uint8_t[:params.c]> params.n_cycle))
            cprrt.PrrtCoding
            return result
rna's avatar
rna committed
169
170
171
172
173
174
175
176

        def __set__(self, params: PrrtCodingConfiguration):
            cdef uint8_t* n_cycle
            c = len(params.n_cycle)
            n_cycle = <uint8_t *> malloc(c * cython.sizeof(int))
            for i, x in enumerate(params.n_cycle):
              n_cycle[i] = x
            cprrt.PrrtSocket_set_coding_parameters(self._c_socket, params.k, params.n, c, n_cycle)
177

178
179
180
181
182
183
    property delivery_rate:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_delivery_rate(self._c_socket)

184
185
186
187
188
189
    property app_limited:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_app_limited(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
190
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
191
192
193
194
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer)
195
        return buffer[:len]
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    def receive_asap(self):
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_receive_asap(self._c_socket, <void*> buffer)
        return buffer[:len]

    def receive_asap_wait(self):
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_receive_asap_wait(self._c_socket, <void*> buffer)
        return buffer[:len]

    def receive_asap_timedwait(self, deadline):
        cdef char buffer[65536]
        cdef int32_t len
        cdef timespec deadline_timespec = timespec(deadline.seconds, deadline.microseconds * 1000)
        with nogil:
            len = cprrt.PrrtSocket_receive_asap_timedwait(self._c_socket, <void*> buffer, &deadline_timespec)
        return buffer[:len]

    def receive_ordered(self, time_window):
        cdef char buffer[65536]
        cdef int32_t len
        cdef uint32_t time_window_us = time_window * (1000**2)
        with nogil:
            len = cprrt.PrrtSocket_receive_ordered(self._c_socket, <void*> buffer, time_window_us)
        return buffer[:len]

227
    def receive_ordered_wait(self, time_window):
228
229
        cdef char buffer[65536]
        cdef int32_t len
230
        cdef uint32_t time_window_us = time_window * (1000**2)
231
        with nogil:
232
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
233
234
        return buffer[:len]

235
236
237
238
239
240
241
242
243
    def receive_ordered_timedwait(self, time_window, deadline):
        cdef char buffer[65536]
        cdef int32_t len
        cdef uint32_t time_window_us = time_window * (1000**2)
        cdef timespec deadline_timespec = timespec(deadline.seconds, deadline.microseconds * 1000)
        with nogil:
            len = cprrt.PrrtSocket_receive_ordered_timedwait(self._c_socket, <void*> buffer, time_window_us, &deadline_timespec)
        return buffer[:len]

244
    def connect(self, host, port):
Andreas Schmidt's avatar
Andreas Schmidt committed
245
246
247
248
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)

    def send(self, data):
249
        cprrt.PrrtSocket_send(self._c_socket, data, len(data))
Andreas Schmidt's avatar
Andreas Schmidt committed
250

251
252
253
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)