from libc.stdint cimport uint32_t, uint16_t, uint8_t, int32_t from libc.stdlib cimport malloc, free cimport cprrt cdef extern from "proto/applicationConstraints.c": pass cdef extern from "proto/stores/dataPacketStore.c": pass cdef extern from "proto/stores/deliveredPacketTable.c": pass cdef extern from "proto/stores/lossGatherer.c": pass cdef extern from "proto/stores/packetTimeoutTable.c": pass cdef extern from "proto/stores/repairBlockStore.c": pass cdef extern from "proto/stores/receiveDataQueue.c": pass cdef extern from "proto/types/packetTimeout.c": pass cdef extern from "proto/processes/feedbackReceiver.c": pass cdef extern from "proto/processes/dataReceiver.c": pass cdef extern from "proto/processes/dataTransmitter.c": pass cdef extern from "proto/block.c": pass cdef extern from "proto/clock.c": pass cdef extern from "proto/channelStateInformation.c": pass cdef extern from "proto/vdmcode/block_code.c": pass cdef extern from "proto/codingParams.c": pass cdef extern from "proto/receiver.c": pass cdef extern from "proto/packet.c": pass cdef extern from "proto/socket.c": pass cdef extern from "util/bptree.c": pass cdef extern from "util/bitmap.c": pass cdef extern from "util/common.c": pass cdef extern from "util/list.c": pass cdef extern from "util/pipe.c": pass 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) 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( self._c_config.n_cycle) cdef class PrrtSocket: cdef cprrt.PrrtSocket* _c_socket cdef bint isSender def __cinit__(self, port, isSender, target_delay = 1, thread_pinning = False): target_delay_us = target_delay * 1000**2 self._c_socket = cprrt.PrrtSocket_create(isSender, target_delay_us) if thread_pinning: cprrt.PrrtSocket_enable_thread_pinning(self._c_socket) cprrt.PrrtSocket_bind(self._c_socket, "0.0.0.0", port) self.isSender = isSender property thread_pinning: def __get__(self): return cprrt.PrrtSocket_uses_thread_pinning(self._c_socket) property target_delay: def __get__(self): if not self.isSender: raise Exception("Not a sender.") return cprrt.PrrtSocket_get_sock_opt(self._c_socket, "targetdelay") * 0.000001 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) property rtt: def __get__(self): if not self.isSender: raise Exception("Not a sender.") return cprrt.PrrtSocket_get_rtt(self._c_socket) * 0.000001 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 def recv(self): cdef char buffer[65536] cdef int32_t len with nogil: len = cprrt.PrrtSocket_recv(self._c_socket, buffer) return buffer[:len] def recv_sync(self, granularity): cdef char buffer[65536] cdef int32_t len cdef uint32_t time_window_us = granularity * (1000**2) with nogil: len = cprrt.PrrtSocket_recv_sync(self._c_socket, buffer, time_window_us) return buffer[:len] def connect(self, host, port): cdef bytes encodedHost = host.encode("utf-8") cprrt.PrrtSocket_connect(self._c_socket, encodedHost, port) def send(self, data): cprrt.PrrtSocket_send(self._c_socket, data, len(data)) def __dealloc__(self): if self._c_socket != NULL: cprrt.PrrtSocket_close(self._c_socket)