prrt.pyx 7.07 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 93 94 95 96 97 98 99
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
100

101
    def __repr__(self):
rna's avatar
rna committed
102
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
103

rna's avatar
rna committed
104 105 106
    #property n_cycle:
    #    def __get__(self):
    #        return list(<uint8_t[:self._c_config.c]> self._c_config.n_cycle)
107

108 109
cdef class PrrtSocket:
    cdef cprrt.PrrtSocket* _c_socket
Andreas Schmidt's avatar
Andreas Schmidt committed
110
    cdef bint isSender
111

112
    def __cinit__(self, port, isSender, target_delay = 1, thread_pinning = False):
113 114
        target_delay_us = target_delay * 1000**2
        self._c_socket = cprrt.PrrtSocket_create(isSender, target_delay_us)
115 116
        if thread_pinning:
            cprrt.PrrtSocket_enable_thread_pinning(self._c_socket)
Andreas Schmidt's avatar
Andreas Schmidt committed
117
        cprrt.PrrtSocket_bind(self._c_socket, "0.0.0.0", port)
Andreas Schmidt's avatar
Andreas Schmidt committed
118

Andreas Schmidt's avatar
Andreas Schmidt committed
119
        self.isSender = isSender
120

Andreas Schmidt's avatar
Andreas Schmidt committed
121 122 123 124 125 126 127
    property plr:

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

128 129 130 131 132
    property thread_pinning:

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

133
    property target_delay:
134

135 136 137
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
138
            return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001
139

140 141 142 143 144 145 146 147 148 149 150
    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)

151
    property rtt:
152 153 154
        def __get__(self):
            if not self.isSender:
                raise Exception("Not a sender.")
155
            return cprrt.PrrtSocket_get_rtprop(self._c_socket) * 0.000001
156

157 158 159 160 161 162
    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)
rna's avatar
rna committed
163 164 165 166 167 168 169 170 171
            return PrrtCodingConfiguration(params.n, params.k, list(<uint8_t[:params.c]> params.n_cycle))

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

173 174 175 176 177 178
    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
179
    def recv(self):
Andreas Schmidt's avatar
Andreas Schmidt committed
180 181 182 183
        cdef char buffer[65536]
        cdef int32_t len
        with nogil:
            len = cprrt.PrrtSocket_recv(self._c_socket, <void*> buffer)
184
        return buffer[:len]
185

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    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]

216
    def receive_ordered_wait(self, time_window):
217 218
        cdef char buffer[65536]
        cdef int32_t len
219
        cdef uint32_t time_window_us = time_window * (1000**2)
220
        with nogil:
221
            len = cprrt.PrrtSocket_receive_ordered_wait(self._c_socket, <void*> buffer, time_window_us)
222 223
        return buffer[:len]

224 225 226 227 228 229 230 231 232
    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]

233
    def connect(self, host, port):
Andreas Schmidt's avatar
Andreas Schmidt committed
234 235 236 237
        cdef bytes encodedHost = host.encode("utf-8")
        cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port)

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

240 241 242
    def __dealloc__(self):
        if self._c_socket != NULL:
            cprrt.PrrtSocket_close(self._c_socket)