prrt.pyx 7.76 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 libc.string cimport memset
4
from posix.time cimport timespec
rna's avatar
rna committed
5
cimport cython
Andreas Schmidt's avatar
Andreas Schmidt committed
6

7 8
cimport cprrt

9 10
include "sockets.pxd"

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

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

17
cdef extern from "proto/stores/deliveredPacketTable.c":
18
    pass
19

Andreas Schmidt's avatar
Andreas Schmidt committed
20 21 22 23
cdef extern from "proto/stores/receptionTable.c":
    pass

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

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

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

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

35
cdef extern from "proto/stores/packetDeliveryStore.c":
36 37
    pass

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

Andreas Schmidt's avatar
Andreas Schmidt committed
41 42 43
cdef extern from "proto/types/lossStatistics.c":
    pass

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

92 93 94
cdef sockaddr_to_addr_and_port(sockaddr_in addr):
    return (cprrt.PrrtSocket_inet_ntoa(&addr.sin_addr), cprrt.PrrtSocket_ntohs(addr.sin_port))

rna's avatar
rna committed
95
class PrrtCodingConfiguration:
96 97 98
    def __init__(self, n, k, n_cycle=None):
        if n < k:
            raise ValueError("n must be greater or equal k.")
rna's avatar
rna committed
99 100
        self.n = n
        self.k = k
101 102 103 104 105 106 107 108 109
        self.r = n - k

        if self.r != 0:
            if n_cycle is None:
                raise ValueError("n_cycle cannot be None if n == k.")
            elif sum(n_cycle) != (n-k):
                raise ValueError("The elements in n_cycle must sum up to n-k.")

        self.n_cycle = n_cycle if n_cycle is not None else [0]
110

111
    def __repr__(self):
rna's avatar
rna committed
112
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
113

114 115 116
    def __repr__(self):
        return "({},{},{})".format(self.n, self.k, self.n_cycle)

117

118 119 120
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket

Andreas Schmidt's avatar
Andreas Schmidt committed
121
    def __cinit__(self, port, target_delay = 1, thread_pinning = False):
122
        target_delay_us = target_delay * 1000**2
Andreas Schmidt's avatar
Andreas Schmidt committed
123
        self._c_socket = cprrt.PrrtSocket_create(target_delay_us)
124 125
        if thread_pinning:
            cprrt.PrrtSocket_enable_thread_pinning(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
126
        cprrt.PrrtSocket_bind(self._c_socket, "0.0.0.0", port)
Andreas Schmidt's avatar
Andreas Schmidt committed
127

Andreas Schmidt's avatar
Andreas Schmidt committed
128

Andreas Schmidt's avatar
Andreas Schmidt committed
129
    property plr_fwd:
Andreas Schmidt's avatar
Andreas Schmidt committed
130
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
131
            return cprrt.PrrtSocket_get_plr_fwd(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
132

133 134 135 136
    property thread_pinning:
        def __get__(self):
            return cprrt.PrrtSocket_uses_thread_pinning(self._c_socket)

137 138
    property target_delay:
        def __get__(self):
139
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
140

141 142 143 144 145 146 147
    property app_queue_size:
        def __get__(self):
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "app_queue_size")

        def __set__(self, value):
            cprrt.PrrtSocket_set_sock_opt(self._c_socket, "app_queue_size", value)

Andreas Schmidt's avatar
Andreas Schmidt committed
148
    property rtt_fwd:
149
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
150
            return cprrt.PrrtSocket_get_rtprop_fwd(self._c_socket) * 0.000001
151

152 153
    property coding_configuration:
        def __get__(self):
154 155
            cdef cprrt.PrrtCodingConfiguration *params = cprrt.PrrtSocket_get_coding_parameters(self._c_socket)
            return PrrtCodingConfiguration(params.n, params.k, list(<uint8_t[:params.c]> params.n_cycle))
rna's avatar
rna committed
156 157 158 159 160 161 162 163

        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)
164

Andreas Schmidt's avatar
Andreas Schmidt committed
165 166 167 168 169
    property delivery_rate_fwd:
        def __get__(self):
            return cprrt.PrrtSocket_get_delivery_rate_fwd(self._c_socket)

    property btlbw_fwd:
170
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
171
            return cprrt.PrrtSocket_get_btlbw_fwd(self._c_socket)
172

Andreas Schmidt's avatar
Andreas Schmidt committed
173
    property btlbw_back:
Andreas Schmidt's avatar
Andreas Schmidt committed
174
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
175
            return cprrt.PrrtSocket_get_btlbw_back(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
176

177 178 179 180
    property app_limited:
        def __get__(self):
            return cprrt.PrrtSocket_get_app_limited(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
181
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
182 183
        cdef char buffer[65536]
        cdef int32_t len
184
        cdef sockaddr_in addr
Andreas Schmidt's avatar
Andreas Schmidt committed
185
        with nogil:
186 187
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
188

189 190 191
    def receive_asap(self):
        cdef char buffer[65536]
        cdef int32_t len
192
        cdef sockaddr_in addr
193
        with nogil:
194 195
            len = cprrt.PrrtSocket_receive_asap(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
196 197 198 199

    def receive_asap_wait(self):
        cdef char buffer[65536]
        cdef int32_t len
200
        cdef sockaddr_in addr
201
        with nogil:
202 203
            len = cprrt.PrrtSocket_receive_asap_wait(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
204 205 206 207

    def receive_asap_timedwait(self, deadline):
        cdef char buffer[65536]
        cdef int32_t len
208
        cdef sockaddr_in addr
209 210
        cdef timespec deadline_timespec = timespec(deadline.seconds, deadline.microseconds * 1000)
        with nogil:
211 212
            len = cprrt.PrrtSocket_receive_asap_timedwait(self._c_socket, <void*> buffer, <sockaddr*> &addr, &deadline_timespec)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
213 214 215 216

    def receive_ordered(self, time_window):
        cdef char buffer[65536]
        cdef int32_t len
217
        cdef sockaddr_in addr
218 219
        cdef uint32_t time_window_us = time_window * (1000**2)
        with nogil:
220 221
            len = cprrt.PrrtSocket_receive_ordered(self._c_socket, <void*> buffer, <sockaddr*> &addr, time_window_us)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
222

223
    def receive_ordered_wait(self, time_window):
224 225
        cdef char buffer[65536]
        cdef int32_t len
226
        cdef sockaddr_in addr
227
        cdef uint32_t time_window_us = time_window * (1000**2)
228
        with nogil:
229 230
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, <sockaddr*> &addr, time_window_us)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
231

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

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

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

249 250 251
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)