prrt.pyx 9.66 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)

Andreas Schmidt's avatar
Andreas Schmidt committed
226 227 228 229 230 231 232 233 234 235 236 237
    property bbr_cwnd:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_cwnd(self._c_socket)

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

238 239 240 241 242 243
    property bbr_pacing_rate:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_pacing_rate(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
244 245 246 247 248 249
    property bbr_send_quantum:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_send_quantum(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
250 251 252 253 254 255
    property bbr_pipe:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_pipe(self._c_socket)

256 257 258 259 260 261
    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
262
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
263 264 265 266
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer)
267
        return buffer[:len]
268

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
    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]

299
    def receive_ordered_wait(self, time_window):
300 301
        cdef char buffer[65536]
        cdef int32_t len
302
        cdef uint32_t time_window_us = time_window * (1000**2)
303
        with nogil:
304
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
305 306
        return buffer[:len]

307 308 309 310 311 312 313 314 315
    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]

316
    def connect(self, host, port):
Andreas Schmidt's avatar
Andreas Schmidt committed
317 318 319 320
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)

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

323 324 325
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)