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

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

98 99 100
cdef sockaddr_to_addr_and_port(sockaddr_in addr):
    return (cprrt.PrrtSocket_inet_ntoa(&addr.sin_addr), cprrt.PrrtSocket_ntohs(addr.sin_port))

101

rna's avatar
rna committed
102
class PrrtCodingConfiguration:
103 104 105
    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
106 107
        self.n = n
        self.k = k
108 109 110 111 112 113 114 115 116
        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]
117

118
    def __repr__(self):
rna's avatar
rna committed
119
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
120

121 122 123
    def __repr__(self):
        return "({},{},{})".format(self.n, self.k, self.n_cycle)

124

125 126 127
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket

128

129 130
    def __cinit__(self, address, target_delay = 1, thread_pinning = False):
        host, port = address
131
        target_delay_us = target_delay * 1000**2
Andreas Schmidt's avatar
Andreas Schmidt committed
132
        self._c_socket = cprrt.PrrtSocket_create(target_delay_us)
133 134
        if thread_pinning:
            cprrt.PrrtSocket_enable_thread_pinning(self._c_socket)
135
        cprrt.PrrtSocket_bind(self._c_socket, host.encode("utf8"), port)
Andreas Schmidt's avatar
Andreas Schmidt committed
136

Andreas Schmidt's avatar
Andreas Schmidt committed
137 138
    # Channel Properties
    property data_rate_btl_fwd:
Andreas Schmidt's avatar
Andreas Schmidt committed
139
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
140
            return cprrt.PrrtSocket_get_btlbw_fwd(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
141

Andreas Schmidt's avatar
Andreas Schmidt committed
142
    property data_rate_btl_back:
Andreas Schmidt's avatar
Andreas Schmidt committed
143
        def __get__(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
144
            return cprrt.PrrtSocket_get_btlbw_back(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
145

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

    property loss_rate_fwd:
        def __get__(self):
            return cprrt.PrrtSocket_get_plr_fwd(self._c_socket)
153 154


Andreas Schmidt's avatar
Andreas Schmidt committed
155
    # Application Properties
156 157
    property target_delay:
        def __get__(self):
158
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
159

Andreas Schmidt's avatar
Andreas Schmidt committed
160 161 162 163 164 165

    # Protocol configuration
    property thread_pinning:
        def __get__(self):
            return cprrt.PrrtSocket_uses_thread_pinning(self._c_socket)

166 167 168 169 170 171 172
    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)

173 174
    property coding_configuration:
        def __get__(self):
175 176
            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
177 178 179 180 181 182 183 184

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

Andreas Schmidt's avatar
Andreas Schmidt committed
186 187 188 189 190
    # Sending
    def connect(self, address):
        host, port = address
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)
Andreas Schmidt's avatar
Andreas Schmidt committed
191

Andreas Schmidt's avatar
Andreas Schmidt committed
192 193
    def send(self, data):
        cprrt.PrrtSocket_send(self._c_socket, data, len(data))
194

Andreas Schmidt's avatar
Andreas Schmidt committed
195

Andreas Schmidt's avatar
Andreas Schmidt committed
196
    # Receiving
Andreas Schmidt's avatar
Andreas Schmidt committed
197
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
198 199
        cdef char buffer[65536]
        cdef int32_t len
200
        cdef sockaddr_in addr
Andreas Schmidt's avatar
Andreas Schmidt committed
201
        with nogil:
202 203
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
204

205 206 207
    def receive_asap(self):
        cdef char buffer[65536]
        cdef int32_t len
208
        cdef sockaddr_in addr
209
        with nogil:
210 211
            len = cprrt.PrrtSocket_receive_asap(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
212 213 214 215

    def receive_asap_wait(self):
        cdef char buffer[65536]
        cdef int32_t len
216
        cdef sockaddr_in addr
217
        with nogil:
218 219
            len = cprrt.PrrtSocket_receive_asap_wait(self._c_socket, <void*> buffer, <sockaddr*> &addr)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
220 221 222 223

    def receive_asap_timedwait(self, deadline):
        cdef char buffer[65536]
        cdef int32_t len
224
        cdef sockaddr_in addr
225 226
        cdef timespec deadline_timespec = timespec(deadline.seconds, deadline.microseconds * 1000)
        with nogil:
227 228
            len = cprrt.PrrtSocket_receive_asap_timedwait(self._c_socket, <void*> buffer, <sockaddr*> &addr, &deadline_timespec)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
229 230 231 232

    def receive_ordered(self, time_window):
        cdef char buffer[65536]
        cdef int32_t len
233
        cdef sockaddr_in addr
234 235
        cdef uint32_t time_window_us = time_window * (1000**2)
        with nogil:
236 237
            len = cprrt.PrrtSocket_receive_ordered(self._c_socket, <void*> buffer, <sockaddr*> &addr, time_window_us)
        return buffer[:len], sockaddr_to_addr_and_port(addr)
238

239
    def receive_ordered_wait(self, time_window):
240 241
        cdef char buffer[65536]
        cdef int32_t len
242
        cdef sockaddr_in addr
243
        cdef uint32_t time_window_us = time_window * (1000**2)
244
        with nogil:
245 246
            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)
247

248 249 250
    def receive_ordered_timedwait(self, time_window, deadline):
        cdef char buffer[65536]
        cdef int32_t len
251
        cdef sockaddr_in addr
252 253 254
        cdef uint32_t time_window_us = time_window * (1000**2)
        cdef timespec deadline_timespec = timespec(deadline.seconds, deadline.microseconds * 1000)
        with nogil:
255 256
            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)
257

Andreas Schmidt's avatar
Andreas Schmidt committed
258

Andreas Schmidt's avatar
Andreas Schmidt committed
259
    # Internals
260 261 262 263 264 265 266 267 268 269 270 271
    property bbr_state:
        def __get__(self):
            return cprrt.PrrtSocket_get_bbr_state(self._c_socket)

    property bbr_filled_pipe:
        def __get__(self):
            return cprrt.PrrtSocket_get_filled_pipe(self._c_socket)

    property bbr_full_bw:
        def __get__(self):
            return cprrt.PrrtSocket_get_full_bw(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
272 273 274 275 276 277 278 279
    property bbr_cycle_index:
        def __get__(self):
            return cprrt.PrrtSocket_get_cycle_index(self._c_socket)

    property bbr_pacing_gain:
        def __get__(self):
            return cprrt.PrrtSocket_get_pacing_gain(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
280 281 282 283 284 285 286 287
    property bbr_cwnd:
        def __get__(self):
            return cprrt.PrrtSocket_get_cwnd(self._c_socket)

    property bbr_inflight:
        def __get__(self):
            return cprrt.PrrtSocket_get_inflight(self._c_socket)

288 289 290 291
    property bbr_pacing_rate:
        def __get__(self):
            return cprrt.PrrtSocket_get_pacing_rate(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
292 293 294 295
    property bbr_send_quantum:
        def __get__(self):
            return cprrt.PrrtSocket_get_send_quantum(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
296 297 298 299
    property bbr_pipe:
        def __get__(self):
            return cprrt.PrrtSocket_get_pipe(self._c_socket)

Andreas Schmidt's avatar
Andreas Schmidt committed
300 301 302 303
    property bbr_delivered:
        def __get__(self):
            return cprrt.PrrtSocket_get_delivered(self._c_socket)

304
    property bbr_is_app_limited:
305
        def __get__(self):
306 307 308 309 310
            return cprrt.PrrtSocket_get_bbr_is_app_limited(self._c_socket)

    property bbr_app_limited:
        def __get__(self):
            return cprrt.PrrtSocket_get_bbr_app_limited(self._c_socket)
311

Andreas Schmidt's avatar
Fixes.  
Andreas Schmidt committed
312 313 314 315
    property bbr_round_start:
        def __get__(self):
            return cprrt.PrrtSocket_get_bbr_round_start(self._c_socket)

316 317 318
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)