prrt.pyx 8.67 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

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

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

59
cdef extern from "proto/channelStateInformation.c":
60
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
61

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

65
cdef extern from "proto/codingParams.c":
66
    pass
67

68
cdef extern from "proto/receiver.c":
69
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
70

71
cdef extern from "proto/types/packet.c":
72
    pass
73

74
cdef extern from "proto/socket.c":
75
    pass
76 77

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

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

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

86 87
cdef extern from "util/list.c":
    pass
88

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

Andreas Schmidt's avatar
Andreas Schmidt committed
92 93 94
cdef extern from "util/mpsc_queue.c":
    pass

Andreas Schmidt's avatar
Andreas Schmidt committed
95 96 97
cdef extern from "util/windowedFilter.c":
    pass

rna's avatar
rna committed
98 99 100 101 102 103 104 105
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
106

107
    def __repr__(self):
rna's avatar
rna committed
108
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
109

110 111 112
    def __repr__(self):
        return "({},{},{})".format(self.n, self.k, self.n_cycle)

rna's avatar
rna committed
113 114 115
    #property n_cycle:
    #    def __get__(self):
    #        return list(<uint8_t[:self._c_config.c]> self._c_config.n_cycle)
116

117 118
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket
Andreas Schmidt's avatar
Andreas Schmidt committed
119
    cdef bint isSender
120

121
    def __cinit__(self, port, isSender, target_delay = 1, thread_pinning = False):
122 123
        target_delay_us = target_delay * 1000**2
        self._c_socket = cprrt.PrrtSocket_create(isSender, 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
        self.isSender = isSender
129

Andreas Schmidt's avatar
Andreas Schmidt committed
130 131 132 133 134 135 136
    property plr:

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

137 138 139 140 141
    property thread_pinning:

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

142
    property target_delay:
143

144 145 146
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
147
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
148

149 150 151 152 153 154 155 156 157 158 159
    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)

160
    property rtt:
161 162 163
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
164
            return cprrt.PrrtSocket_get_rtprop(self._c_socket) * 0.000001
165

166 167 168 169 170 171
    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)
172 173
            result = PrrtCodingConfiguration(params.n, params.k, list(<uint8_t[:params.c]> params.n_cycle))
            return result
rna's avatar
rna committed
174 175 176 177 178 179 180 181

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

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

Andreas Schmidt's avatar
Andreas Schmidt committed
189 190 191 192 193 194
    property btlbw:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_btlbw(self._c_socket)

195 196 197 198 199 200 201 202 203 204 205 206
    property bbr_state:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_bbr_state(self._c_socket)

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

Andreas Schmidt's avatar
Andreas Schmidt committed
207

208 209 210 211 212 213
    property bbr_full_bw:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_full_bw(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
214 215 216 217 218 219 220 221 222 223 224 225
    property bbr_cycle_index:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_cycle_index(self._c_socket)

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

226 227 228 229 230 231
    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
232
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
233 234 235 236
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer)
237
        return buffer[:len]
238

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
    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]

269
    def receive_ordered_wait(self, time_window):
270 271
        cdef char buffer[65536]
        cdef int32_t len
272
        cdef uint32_t time_window_us = time_window * (1000**2)
273
        with nogil:
274
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
275 276
        return buffer[:len]

277 278 279 280 281 282 283 284 285
    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]

286
    def connect(self, host, port):
Andreas Schmidt's avatar
Andreas Schmidt committed
287 288 289 290
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)

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

293 294 295
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)