prrt.pyx 7.72 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
class PrrtCodingConfiguration:
93 94 95
    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
96 97
        self.n = n
        self.k = k
98 99 100 101 102 103 104 105 106
        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]
107

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

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

114

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

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

Andreas Schmidt's avatar
Andreas Schmidt committed
126
        self.isSender = isSender
127

Andreas Schmidt's avatar
Andreas Schmidt committed
128 129 130 131 132 133 134
    property plr:

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

135 136 137 138 139
    property thread_pinning:

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

140
    property target_delay:
141

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

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

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

164 165 166 167
    property coding_configuration:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
168 169
            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
170 171 172 173 174 175 176 177

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

179 180 181 182 183 184
    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
185 186 187 188 189 190
    property btlbw:
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            return cprrt.PrrtSocket_get_btlbw(self._c_socket)

191 192 193 194 195 196
    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
197
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
198 199 200 201
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer)
202
        return buffer[:len]
203

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    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]

234
    def receive_ordered_wait(self, time_window):
235 236
        cdef char buffer[65536]
        cdef int32_t len
237
        cdef uint32_t time_window_us = time_window * (1000**2)
238
        with nogil:
239
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
240 241
        return buffer[:len]

242 243 244 245 246 247 248 249 250
    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]

251
    def connect(self, host, port):
Andreas Schmidt's avatar
Andreas Schmidt committed
252 253 254 255
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)

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

258 259 260
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)