prrt.pyx 7.22 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
Andreas Schmidt's avatar
Andreas Schmidt committed
4

5 6
cimport cprrt

7
cdef extern from "proto/applicationConstraints.c":
8 9
    pass

10
cdef extern from "proto/stores/dataPacketStore.c":
11 12
    pass

13
cdef extern from "proto/stores/deliveredPacketTable.c":
14
    pass
15

Andreas Schmidt's avatar
Andreas Schmidt committed
16 17 18 19
cdef extern from "proto/stores/receptionTable.c":
    pass

cdef extern from "proto/stores/packetTimeoutTable.c":
20 21
    pass

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

25 26 27
cdef extern from "proto/stores/inFlightPacketStore.c":
    pass

28
cdef extern from "proto/stores/repairBlockStore.c":
29 30
    pass

31
cdef extern from "proto/stores/packetDeliveryStore.c":
32 33
    pass

Andreas Schmidt's avatar
Andreas Schmidt committed
34 35 36
cdef extern from "proto/types/packetTimeout.c":
    pass

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

40
cdef extern from "proto/processes/feedbackReceiver.c":
41
    pass
42

43
cdef extern from "proto/processes/dataReceiver.c":
44
    pass
45

46
cdef extern from "proto/processes/dataTransmitter.c":
47
    pass
48

49
cdef extern from "proto/block.c":
50
    pass
51

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

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

58
cdef extern from "proto/vdmcode/block_code.c":
59
    pass
60

61
cdef extern from "proto/codingParams.c":
62
    pass
63

64
cdef extern from "proto/receiver.c":
65
    pass
Andreas Schmidt's avatar
Andreas Schmidt committed
66

67
cdef extern from "proto/types/packet.c":
68
    pass
69

70
cdef extern from "proto/socket.c":
71
    pass
72 73

cdef extern from "util/bptree.c":
74
    pass
75

76 77
cdef extern from "util/bitmap.c":
    pass
78

79 80 81
cdef extern from "util/common.c":
    pass

82 83
cdef extern from "util/list.c":
    pass
84

Andreas Schmidt's avatar
Andreas Schmidt committed
85 86 87
cdef extern from "util/pipe.c":
    pass

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

91 92 93 94 95 96 97 98 99 100
cdef class PrrtCodingConfiguration:
    cdef cprrt.PrrtCodingParams* _c_config

    def __cinit__(self):
        self._c_config = cprrt.PrrtCodingParams_create()

    def __dealloc__(self):
        if self._c_config != NULL:
            cprrt.PrrtCodingParams_destroy(self._c_config)

101 102 103
    def __repr__(self):
        return "PrrtCodingConfiguration(n={},k={},n_cycle=[{}])".format(self.n, self.k, ",".join(map(str, self.n_cycle)))

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
    cdef copy(self, cprrt.PrrtCodingParams* other):
        cprrt.PrrtCodingParams_destroy(self._c_config)
        self._c_config = other

    property k:
        def __get__(self):
            return int(self._c_config.k)
    property n:
        def __get__(self):
            return int(self._c_config.n)
    property r:
        def __get__(self):
            return int(self._c_config.r)
    property c:
        def __get__(self):
            return int(self._c_config.c)
    property n_cycle:
        def __get__(self):
            return list(<uint8_t[:self._c_config.c]> self._c_config.n_cycle)

124 125
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket
Andreas Schmidt's avatar
Andreas Schmidt committed
126
    cdef bint isSender
127

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

Andreas Schmidt's avatar
Andreas Schmidt committed
135
        self.isSender = isSender
136

Andreas Schmidt's avatar
Andreas Schmidt committed
137 138 139 140 141 142 143
    property plr:

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

144 145 146 147 148
    property thread_pinning:

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

149
    property target_delay:
150

151 152 153
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
154
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
155

156 157 158 159 160 161 162 163 164 165 166
    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)

167
    property rtt:
168 169 170
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
171
            return cprrt.PrrtSocket_get_rtprop(self._c_socket) * 0.000001
172

173 174 175 176 177 178 179 180 181 182
    property coding_configuration:

        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
            res = PrrtCodingConfiguration()
            cdef cprrt.PrrtCodingParams *params = cprrt.PrrtSocket_get_coding_parameters(self._c_socket)
            res.copy(params)
            return res

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

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
    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]

226
    def receive_ordered_wait(self, time_window):
227 228
        cdef char buffer[65536]
        cdef int32_t len
229
        cdef uint32_t time_window_us = time_window * (1000**2)
230
        with nogil:
231
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
232 233
        return buffer[:len]

234 235 236 237 238 239 240 241 242
    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]

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

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

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