summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@ugent.be>2017-08-30 17:11:22 +0200
committerdimitri staessens <dimitri.staessens@ugent.be>2017-08-31 09:18:41 +0200
commit4060efec26115dbb9e68da67bc482a12b4f80ea8 (patch)
tree559ab25cc65cbac1ddda458f8370e8ee2675edf8
parent8fe0340d2117cf9b5c724ff10621978ef2bee5f1 (diff)
downloadouroboros-4060efec26115dbb9e68da67bc482a12b4f80ea8.tar.gz
ouroboros-4060efec26115dbb9e68da67bc482a12b4f80ea8.zip
lib: Add fccntl configuration command
This replaces the flow_set_* commands with a single fccntl command that can configure flows and the FRCT instance. For more details, see "man 3 fccntl".
-rw-r--r--doc/man/CMakeLists.txt1
-rw-r--r--doc/man/fccntl.3119
-rw-r--r--doc/man/fqueue.32
-rw-r--r--include/ouroboros/CMakeLists.txt2
-rw-r--r--include/ouroboros/fccntl.h67
-rw-r--r--include/ouroboros/fcntl.h59
-rw-r--r--include/ouroboros/frct_pci.h10
-rw-r--r--include/ouroboros/qos.h13
-rw-r--r--include/ouroboros/wrap/CMakeLists.txt2
-rw-r--r--include/ouroboros/wrap/ouroboros.i4
-rw-r--r--src/lib/cdap.c1
-rw-r--r--src/lib/dev.c280
-rw-r--r--src/lib/frct_pci.c2
-rw-r--r--src/lib/qos.c6
-rw-r--r--src/tools/cbr/cbr_server.c4
-rw-r--r--src/tools/operf/operf_client.c4
-rw-r--r--src/tools/oping/oping_client.c4
-rw-r--r--src/tools/oping/oping_server.c2
18 files changed, 339 insertions, 243 deletions
diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt
index 280252ed..ab56242d 100644
--- a/doc/man/CMakeLists.txt
+++ b/doc/man/CMakeLists.txt
@@ -7,6 +7,7 @@ set(MAN_NAMES
flow_dealloc.3
flow_read.3
flow_write.3
+ fccntl.3
fqueue.3
fqueue_create.3
fqueue_destroy.3
diff --git a/doc/man/fccntl.3 b/doc/man/fccntl.3
new file mode 100644
index 00000000..20a1bf89
--- /dev/null
+++ b/doc/man/fccntl.3
@@ -0,0 +1,119 @@
+.\" Ouroboros man pages (C) 2017
+.\" Dimitri Staessens <dimitri.staessens@ugent.be>
+.\" Sander Vrijders <sander.vrijders@ugent.be>
+
+.TH FCCNTL 3 2017-08-30 GNU "Ouroboros Programmer's Manual"
+
+.SH NAME
+
+fccntl \- control commands for flows and FRCT connections
+
+.SH SYNOPSIS
+
+.B #include <ouroboros/fccntl.h>
+
+\fBint fccntl(int \fIfd\fB, int \fIcmd\fB, ...);
+
+Compile and link with \fI-louroboros\fR.
+
+.SH DESCRIPTION
+
+\fBfccntl\fR() is used to control the configuration of flows and
+connections.
+
+Supported commands are:
+
+\fBFLOWSSNDTIMEO\fR - set the sender timeout. Takes a \fBstruct
+timespec * \fItimeo\fR as third argument. Passing NULL for \fItimeo\fR
+disables the timeout.
+
+\fBFLOWGSNDTIMEO\fR - retrieve the current sender timeout. Takes a
+\fBstruct timespec * \fItimeo\fR as third argument.
+
+\fBFLOWSRCVTIMEO\fR - set the receiver timeout. Takes a \fBstruct
+timespec * \fItimeo\fR as third argument. Passing NULL for \fItimeo\fR
+disables the timeout.
+
+\fBFLOWGRCVTIMEO\fR - retrieve the current receiver timeout. Takes a
+\fBstruct timespec * \fItimeo\fR as third argument.
+
+\fBFLOWGQOSSPEC\fR - retrieve the current QoS specification of the
+flow. Takes a \fBqosspec_t * \fIqs\fR as third argument.
+
+\fBFLOWSFLAGS\fR - set flow flags. Takes flow flags as third
+argument. Supported flags are:
+
+ \fIFLOWFRDONLY\fR - set flow to read-only.
+
+ \fIFLOWFWRONLY\fR - set flow_to write-only.
+
+ \fIFLOWFRDWR\fR - set flow to read-write.
+
+ \fIFLOWFNONBLOCK\fR - set I/O to non-blocking.
+
+ \fIFLOWFDEFAULT\fR - set flow defaults (blocking, read-write).
+
+\fBFLOWGFLAGS\fR - get the current flow flags. Takes an \fBuint32_t
+\fIflags\fR as third argument.
+
+\fBFRCTSFLAGS\fR - set FRCT flags. Takes FRCT flags as third
+argument. Supported flags are:
+
+ \fIFRCTFRESCNTRL\fR - enable resource control.
+
+ \fIFRCTFRTX\fR - enable retransmission.
+
+ \fIFRCTFERRCHCK\fR - enable checksum (CRC32).
+
+ \fIFRCTFORDERING\fR - enable packet in-order delivery.
+
+ \fIFRCTFPARTIAL\fR - enable partial delivery.
+
+\fBFRCTGFLAGS\fR - get the current flow flags. Takes an \fBuint16_t
+\fIflags\fR as third argument.
+
+.SH RETURN VALUE
+
+On success, \fBfccntl\fR() returns 0.
+
+.SH ERRORS
+
+\fBfccntl\fR() can return
+
+.B -EINVAL
+An invalid argument was passed.
+
+.B -EPERM
+Operation not permitted. This is returned when requesting the value of
+a timeout (FLOWGSNDTIMEO or FLOWGRCVTIMEO) when no such timeout was
+set.
+
+.B -EBADF
+Invalid flow descriptor passed.
+
+.B -ENOTALLOC
+Flow is not allocated.
+
+.B -ENOTSUP
+The specified command is not supported.
+
+.SH ATTRIBUTES
+
+For an explanation of the terms used in this section, see \fBattributes\fR(7).
+
+.TS
+box, tab(&);
+LB|LB|LB
+L|L|L.
+Interface & Attribute & Value
+_
+\fBfccntl\fR() & Thread safety & MT-Safe
+.TE
+
+.SH SEE ALSO
+
+.BR flow_alloc "(3), " flow_accept "(3), " flow_dealloc "(3), " fqueue (3)
+
+.SH COLOPHON
+This page is part of the Ouroboros project, found at
+https://bitbucket.org/ouroboros-rina/ouroboros
diff --git a/doc/man/fqueue.3 b/doc/man/fqueue.3
index 611d54c7..cf8cef20 100644
--- a/doc/man/fqueue.3
+++ b/doc/man/fqueue.3
@@ -26,8 +26,6 @@ Compile and link with \fI-louroboros\fR.
.SH DESCRIPTION
-These calls are used to
-
The \fBfqueue_create\fR() function creates an fqueue_t structure which
is an event queue that stores events that occured within a certain
\fBfset_t\fR.
diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt
index e39759fd..b6edac53 100644
--- a/include/ouroboros/CMakeLists.txt
+++ b/include/ouroboros/CMakeLists.txt
@@ -4,7 +4,7 @@ set(HEADER_FILES
cdefs.h
dev.h
errno.h
- fcntl.h
+ fccntl.h
fqueue.h
ipcp.h
irm.h
diff --git a/include/ouroboros/fccntl.h b/include/ouroboros/fccntl.h
new file mode 100644
index 00000000..d938439f
--- /dev/null
+++ b/include/ouroboros/fccntl.h
@@ -0,0 +1,67 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Flow and FRCT connection control
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#ifndef OUROBOROS_FCCNTL_H
+#define OUROBOROS_FCCNTL_H
+
+#include <ouroboros/cdefs.h>
+
+#include <sys/time.h>
+
+/* Flow flags, same values as fcntl.h */
+#define FLOWFRDONLY 00000000 /* Read-only flow */
+#define FLOWFWRONLY 00000001 /* Write-only flow */
+#define FLOWFRDWR 00000002 /* Read-write flow */
+#define FLOWFACCMODE 00000003 /* Access mask */
+
+#define FLOWFNONBLOCK 00004000 /* Non-blocking flow */
+#define FLOWFDEFAULT 00000002 /* Default, blocking, rw */
+
+#define FLOWFINVALID (FLOWFWRONLY | FLOWFRDWR)
+
+/* FRCT flags */
+#define FRCTFRESCNTRL 00000001 /* Feedback from receiver */
+#define FRCTFRTX 00000002 /* Reliable flow */
+#define FRCTFERRCHCK 00000004 /* Check for errors */
+#define FRCTFORDERING 00000010 /* Ordered delivery */
+#define FRCTFPARTIAL 00000020 /* Allow partial delivery */
+
+/* Operations */
+#define FLOWSRCVTIMEO 00000001 /* Set read timeout */
+#define FLOWGRCVTIMEO 00000002 /* Get read timeout */
+#define FLOWSSNDTIMEO 00000003 /* Set send timeout */
+#define FLOWGSNDTIMEO 00000004 /* Get send timeout */
+#define FLOWGQOSSPEC 00000005 /* Get qosspec_t */
+#define FLOWSFLAGS 00000006 /* Set flags for flow */
+#define FLOWGFLAGS 00000007 /* Get flags for flow */
+#define FRCTSFLAGS 00000010 /* Set flags for FRCT */
+#define FRCTGFLAGS 00000011 /* Get flags for FRCT */
+
+__BEGIN_DECLS
+
+int fccntl(int fd,
+ int cmd,
+ ...);
+
+__END_DECLS
+
+#endif /* OUROBOROS_FCCNTL_H */
diff --git a/include/ouroboros/fcntl.h b/include/ouroboros/fcntl.h
deleted file mode 100644
index 655a0a03..00000000
--- a/include/ouroboros/fcntl.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Flows
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_FCNTL_H
-#define OUROBOROS_FCNTL_H
-
-#include <ouroboros/cdefs.h>
-
-#include <sys/time.h>
-
-/* same values as fcntl.h */
-#define FLOW_O_RDONLY 00000000
-#define FLOW_O_WRONLY 00000001
-#define FLOW_O_RDWR 00000002
-#define FLOW_O_ACCMODE 00000003
-
-#define FLOW_O_NONBLOCK 00004000
-#define FLOW_O_DEFAULT 00000002
-
-#define FLOW_O_INVALID (FLOW_O_WRONLY | FLOW_O_RDWR)
-
-__BEGIN_DECLS
-
-int flow_set_flags(int fd,
- int flags);
-
-int flow_get_flags(int fd);
-
-int flow_set_timeout(int fd,
- const struct timespec * to);
-
-int flow_get_timeout(int fd,
- struct timespec * to);
-
-int flow_get_qosspec(int fd,
- qosspec_t * qs);
-
-__END_DECLS
-
-#endif /* OUROBOROS_FCNTL_H */
diff --git a/include/ouroboros/frct_pci.h b/include/ouroboros/frct_pci.h
index 601c0ce4..a919bc60 100644
--- a/include/ouroboros/frct_pci.h
+++ b/include/ouroboros/frct_pci.h
@@ -35,7 +35,7 @@ struct frct_pci {
uint64_t seqno;
/* Present in config PDU. */
- uint8_t conf_flags;
+ uint16_t conf_flags;
/* Present in flow control PDU. */
uint64_t lwe;
@@ -51,14 +51,6 @@ enum pdu_types {
PDU_TYPE_RENDEZ_VOUS = 0x10
};
-enum config_flags {
- CONF_RESOURCE_CONTROL = 0x01,
- CONF_RELIABLE = 0x02,
- CONF_ERROR_CHECK = 0x04,
- CONF_ORDERED = 0x08,
- CONF_PARTIAL = 0x10
-};
-
enum data_flags {
FLAG_DATA_RUN = 0x01,
FLAG_MORE_FRAGMENTS = 0x02
diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h
index f68df911..3d43dc31 100644
--- a/include/ouroboros/qos.h
+++ b/include/ouroboros/qos.h
@@ -31,15 +31,14 @@ typedef struct qos_spec {
uint64_t bandwidth; /* In bits/s */
uint8_t availability; /* Class of 9s */
uint32_t maximum_interruption; /* In ms */
-
- bool resource_control; /* Feedback from receiver */
- bool reliable; /* Reliable flow */
- bool error_check; /* Check for errors */
- bool ordered; /* Ordered delivery */
- bool partial; /* Allow partial delivery */
} qosspec_t;
+__BEGIN_DECLS
+
int qosspec_init(qosspec_t * qs);
+
int qosspec_fini(qosspec_t * qs);
-#endif
+__END_DECLS
+
+#endif /* OUROBOROS_QOS_H */
diff --git a/include/ouroboros/wrap/CMakeLists.txt b/include/ouroboros/wrap/CMakeLists.txt
index 435b3b70..44c652d5 100644
--- a/include/ouroboros/wrap/CMakeLists.txt
+++ b/include/ouroboros/wrap/CMakeLists.txt
@@ -17,6 +17,8 @@ else ()
# Python assumes C99 since Python 3.6
test_and_set_c_compiler_flag_global(-std=c99)
+ # SWIG generates code for varargs with an unused parameter
+ test_and_set_c_compiler_flag_global(-Wno-unused-parameter)
# CMake > 3.8 deprecates swig_add_module
if (${CMAKE_VERSION} VERSION_LESS 3.8.0)
diff --git a/include/ouroboros/wrap/ouroboros.i b/include/ouroboros/wrap/ouroboros.i
index 4bf343b9..ebda2453 100644
--- a/include/ouroboros/wrap/ouroboros.i
+++ b/include/ouroboros/wrap/ouroboros.i
@@ -26,7 +26,7 @@
#include "ouroboros/cdap.h"
#include "ouroboros/dev.h"
#include "ouroboros/errno.h"
-#include "ouroboros/fcntl.h"
+#include "ouroboros/fccntl.h"
#include "ouroboros/fqueue.h"
#include "ouroboros/irm.h"
#include "ouroboros/ipcp.h"
@@ -41,7 +41,7 @@ typedef int pid_t;
%include "ouroboros/cdap.h"
%include "ouroboros/dev.h"
%include "ouroboros/errno.h"
-%include "ouroboros/fcntl.h"
+%include "ouroboros/fccntl.h"
%include "ouroboros/fqueue.h"
%include "ouroboros/irm.h"
%include "ouroboros/ipcp.h"
diff --git a/src/lib/cdap.c b/src/lib/cdap.c
index 7d2feae3..d9cb2036 100644
--- a/src/lib/cdap.c
+++ b/src/lib/cdap.c
@@ -26,7 +26,6 @@
#include <ouroboros/bitmap.h>
#include <ouroboros/dev.h>
#include <ouroboros/fqueue.h>
-#include <ouroboros/fcntl.h>
#include <ouroboros/errno.h>
#include "cdap_req.h"
diff --git a/src/lib/dev.c b/src/lib/dev.c
index d5044fb3..e02d66d0 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -29,7 +29,7 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/local-dev.h>
#include <ouroboros/sockets.h>
-#include <ouroboros/fcntl.h>
+#include <ouroboros/fccntl.h>
#include <ouroboros/bitmap.h>
#include <ouroboros/shm_flow_set.h>
#include <ouroboros/shm_rdrbuff.h>
@@ -43,6 +43,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
#define BUF_SIZE 1500
@@ -86,7 +87,7 @@ struct frcti {
uint64_t rcv_lwe;
uint64_t rcv_rwe;
- uint8_t conf_flags;
+ uint16_t conf_flags;
};
struct port {
@@ -108,7 +109,9 @@ struct flow {
pid_t api;
- bool timesout;
+ bool snd_timesout;
+ bool rcv_timesout;
+ struct timespec snd_timeo;
struct timespec rcv_timeo;
};
@@ -309,7 +312,7 @@ static int frcti_send(int fd,
pci->seqno = frcti->snd_lwe++;
- if (frct_pci_ser(sdb, pci, frcti->conf_flags & CONF_ERROR_CHECK)) {
+ if (frct_pci_ser(sdb, pci, frcti->conf_flags & FRCTFERRCHCK)) {
pthread_rwlock_unlock(&ai.lock);
return -1;
}
@@ -325,8 +328,8 @@ static int frcti_send(int fd,
}
-static int frcti_configure(int fd,
- qosspec_t * qos)
+static int frcti_configure(int fd,
+ uint16_t flags)
{
struct frcti * frcti;
struct frct_pci pci;
@@ -336,22 +339,10 @@ static int frcti_configure(int fd,
memset(&pci, 0, sizeof(pci));
- if (qos == NULL)
- return 0;
-
if (ipcp_sdb_reserve(&sdb, 0))
return -1;
- if (qos->resource_control)
- pci.conf_flags |= CONF_RESOURCE_CONTROL;
- if (qos->reliable)
- pci.conf_flags |= CONF_RELIABLE;
- if (qos->error_check)
- pci.conf_flags |= CONF_ERROR_CHECK;
- if (qos->ordered)
- pci.conf_flags |= CONF_ORDERED;
- if (qos->partial)
- pci.conf_flags |= CONF_PARTIAL;
+ pci.conf_flags = flags;
/* Always set the DRF on a configure message. */
pci.flags |= FLAG_DATA_RUN;
@@ -385,49 +376,50 @@ static int frcti_write(int fd,
static ssize_t frcti_read(int fd)
{
- ssize_t idx = -1;
- struct timespec abstime;
+ ssize_t idx;
struct frcti * frcti;
struct frct_pci pci;
struct shm_du_buff * sdb;
- struct timespec now = {0, 0};
do {
- pthread_rwlock_rdlock(&ai.lock);
+ struct timespec now;
+ struct timespec abs;
+ struct timespec * abstime = NULL;
+ struct shm_rbuff * rb;
+ bool noblock;
- if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) {
- idx = shm_rbuff_read(ai.flows[fd].rx_rb);
- pthread_rwlock_unlock(&ai.lock);
- } else {
- struct shm_rbuff * rb = ai.flows[fd].rx_rb;
- bool timeo = ai.flows[fd].timesout;
- struct timespec timeout = ai.flows[fd].rcv_timeo;
+ clock_gettime(PTHREAD_COND_CLOCK, &now);
- pthread_rwlock_unlock(&ai.lock);
+ pthread_rwlock_rdlock(&ai.lock);
+
+ noblock = ai.flows[fd].oflags & FLOWFNONBLOCK;
+ rb = ai.flows[fd].rx_rb;
- if (timeo) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, &timeout, &abstime);
- idx = shm_rbuff_read_b(rb, &abstime);
- } else {
- idx = shm_rbuff_read_b(rb, NULL);
- }
+ if (ai.flows[fd].rcv_timesout) {
+ ts_add(&now, &ai.flows[fd].rcv_timeo, &abs);
+ abstime = &abs;
}
+ pthread_rwlock_unlock(&ai.lock);
+
+ if (noblock)
+ idx = shm_rbuff_read(rb);
+ else
+ idx = shm_rbuff_read_b(rb, abstime);
+
if (idx < 0)
return idx;
clock_gettime(CLOCK_REALTIME_COARSE, &now);
- pthread_rwlock_wrlock(&ai.lock);
-
frcti = &(ai.frcti[fd]);
sdb = shm_rdrbuff_get(ai.rdrb, idx);
+ pthread_rwlock_wrlock(&ai.lock);
+
/* SDU may be corrupted. */
- if (frct_pci_des(sdb, &pci,
- frcti->conf_flags & CONF_ERROR_CHECK)) {
+ if (frct_pci_des(sdb, &pci, frcti->conf_flags & FRCTFERRCHCK)) {
pthread_rwlock_unlock(&ai.lock);
shm_rdrbuff_remove(ai.rdrb, idx);
return -EAGAIN;
@@ -538,7 +530,7 @@ static int flow_init(int port_id,
}
ai.flows[fd].port_id = port_id;
- ai.flows[fd].oflags = FLOW_O_DEFAULT;
+ ai.flows[fd].oflags = FLOWFDEFAULT;
ai.flows[fd].api = api;
ai.flows[fd].cube = qc;
ai.flows[fd].spec = qos_cube_to_spec(qc);
@@ -821,7 +813,7 @@ int flow_alloc(const char * dst_name,
pthread_rwlock_unlock(&ai.lock);
- if (frcti_configure(fd, qs)) {
+ if (frcti_configure(fd, FRCTFORDERING | FRCTFERRCHCK)) {
flow_fini(fd);
bmp_release(ai.fds, fd);
return -1;
@@ -872,123 +864,113 @@ int flow_dealloc(int fd)
return 0;
}
-int flow_set_flags(int fd,
- int flags)
+int fccntl(int fd,
+ int cmd,
+ ...)
{
- int old;
+ uint32_t * fflags;
+ uint16_t * cflags;
+ va_list l;
+ struct timespec * timeo;
+ qosspec_t * qs;
if (fd < 0 || fd >= AP_MAX_FLOWS)
return -EBADF;
- pthread_rwlock_wrlock(&ai.lock);
-
- if (ai.flows[fd].port_id < 0) {
- pthread_rwlock_unlock(&ai.lock);
- return -ENOTALLOC;
- }
-
- old = ai.flows[fd].oflags;
-
- ai.flows[fd].oflags = flags;
- if (flags & FLOW_O_WRONLY)
- shm_rbuff_block(ai.flows[fd].rx_rb);
- if (flags & FLOW_O_RDWR)
- shm_rbuff_unblock(ai.flows[fd].rx_rb);
-
- pthread_rwlock_unlock(&ai.lock);
-
- return old;
-}
-
-int flow_get_flags(int fd)
-{
- int old;
-
- if (fd < 0 || fd >= AP_MAX_FLOWS)
- return -EBADF;
+ va_start(l, cmd);
pthread_rwlock_wrlock(&ai.lock);
if (ai.flows[fd].port_id < 0) {
pthread_rwlock_unlock(&ai.lock);
+ va_end(l);
return -ENOTALLOC;
}
- old = ai.flows[fd].oflags;
-
- pthread_rwlock_unlock(&ai.lock);
-
- return old;
-}
-
-int flow_get_timeout(int fd,
- struct timespec * timeo)
-{
- int ret = 0;
-
- if (fd < 0 || fd > AP_MAX_FLOWS || timeo == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&ai.lock);
-
- if (ai.flows[fd].port_id < 0) {
+ switch(cmd) {
+ case FLOWSSNDTIMEO:
+ timeo = va_arg(l, struct timespec *);
+ if (timeo == NULL) {
+ ai.flows[fd].snd_timesout = false;
+ } else {
+ ai.flows[fd].snd_timesout = true;
+ ai.flows[fd].snd_timeo = *timeo;
+ }
+ break;
+ case FLOWGSNDTIMEO:
+ timeo = va_arg(l, struct timespec *);
+ if (timeo == NULL)
+ goto einval;
+ if (!ai.flows[fd].snd_timesout)
+ goto eperm;
+ *timeo = ai.flows[fd].snd_timeo;
+ break;
+ case FLOWSRCVTIMEO:
+ timeo = va_arg(l, struct timespec *);
+ if (timeo == NULL) {
+ ai.flows[fd].rcv_timesout = false;
+ } else {
+ ai.flows[fd].rcv_timesout = true;
+ ai.flows[fd].rcv_timeo = *timeo;
+ }
+ break;
+ case FLOWGRCVTIMEO:
+ timeo = va_arg(l, struct timespec *);
+ if (timeo == NULL)
+ goto einval;
+ if (!ai.flows[fd].rcv_timesout)
+ goto eperm;
+ *timeo = ai.flows[fd].snd_timeo;
+ break;
+ case FLOWGQOSSPEC:
+ qs = va_arg(l, qosspec_t *);
+ if (qs == NULL)
+ goto einval;
+ *qs = ai.flows[fd].spec;
+ break;
+ case FLOWSFLAGS:
+ ai.flows[fd].oflags = va_arg(l, uint32_t);
+ if (ai.flows[fd].oflags & FLOWFWRONLY)
+ shm_rbuff_block(ai.flows[fd].rx_rb);
+ if (ai.flows[fd].oflags & FLOWFRDWR)
+ shm_rbuff_unblock(ai.flows[fd].rx_rb);
+ break;
+ case FLOWGFLAGS:
+ fflags = va_arg(l, uint32_t *);
+ if (fflags == NULL)
+ goto einval;
+ *fflags = ai.flows[fd].oflags;
+ break;
+ case FRCTSFLAGS:
+ ai.frcti[fd].conf_flags = (uint16_t) va_arg(l, int);
+ break;
+ case FRCTGFLAGS:
+ cflags = (uint16_t *) va_arg(l, int *);
+ if (cflags == NULL)
+ goto einval;
+ *cflags = ai.frcti[fd].conf_flags;
+ break;
+ default:
pthread_rwlock_unlock(&ai.lock);
- return -ENOTALLOC;
- }
+ va_end(l);
+ return -ENOTSUP;
- if (ai.flows[fd].timesout)
- *timeo = ai.flows[fd].rcv_timeo;
- else
- ret = -EPERM;
+ };
pthread_rwlock_unlock(&ai.lock);
- return ret;
-}
-
-int flow_set_timeout(int fd,
- const struct timespec * timeo)
-{
- if (fd < 0 || fd > AP_MAX_FLOWS)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&ai.lock);
-
- if (ai.flows[fd].port_id < 0) {
- pthread_rwlock_unlock(&ai.lock);
- return -ENOTALLOC;
- }
-
- if (timeo == NULL) {
- ai.flows[fd].timesout = false;
- } else {
- ai.flows[fd].timesout = true;
- ai.flows[fd].rcv_timeo = *timeo;
- }
-
- pthread_rwlock_unlock(&ai.lock);
+ va_end(l);
return 0;
-}
-
-int flow_get_qosspec(int fd,
- qosspec_t * qs)
-{
- if (fd < 0 || fd > AP_MAX_FLOWS || qs == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&ai.lock);
-
- if (ai.flows[fd].port_id < 0) {
- pthread_rwlock_unlock(&ai.lock);
- return -ENOTALLOC;
- }
-
- *qs = ai.flows[fd].spec;
+ einval:
pthread_rwlock_unlock(&ai.lock);
-
- return 0;
+ va_end(l);
+ return -EINVAL;
+ eperm:
+ pthread_rwlock_unlock(&ai.lock);
+ va_end(l);
+ return -EPERM;
}
ssize_t flow_write(int fd,
@@ -1010,12 +992,12 @@ ssize_t flow_write(int fd,
return -ENOTALLOC;
}
- if ((ai.flows[fd].oflags & FLOW_O_ACCMODE) == FLOW_O_RDONLY) {
+ if ((ai.flows[fd].oflags & FLOWFACCMODE) == FLOWFRDONLY) {
pthread_rwlock_unlock(&ai.lock);
return -EPERM;
}
- if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) {
+ if (ai.flows[fd].oflags & FLOWFNONBLOCK) {
idx = shm_rdrbuff_write(ai.rdrb,
DU_BUFF_HEADSPACE,
DU_BUFF_TAILSPACE,
@@ -1062,10 +1044,11 @@ ssize_t flow_read(int fd,
void * buf,
size_t count)
{
- ssize_t idx = -1;
- ssize_t n;
- uint8_t * sdu;
- bool used;
+ ssize_t idx;
+ ssize_t n;
+ uint8_t * sdu;
+ bool used;
+ struct shm_rbuff * rb;
if (fd < 0 || fd > AP_MAX_FLOWS)
return -EBADF;
@@ -1078,11 +1061,12 @@ ssize_t flow_read(int fd,
}
used = ai.frcti[fd].used;
+ rb = ai.flows[fd].rx_rb;
pthread_rwlock_unlock(&ai.lock);
if (!used)
- idx = shm_rbuff_read(ai.flows[fd].rx_rb);
+ idx = shm_rbuff_read(rb);
else
idx = frcti_read(fd);
@@ -1477,7 +1461,7 @@ int ipcp_flow_write(int fd,
return -ENOTALLOC;
}
- if ((ai.flows[fd].oflags & FLOW_O_ACCMODE) == FLOW_O_RDONLY) {
+ if ((ai.flows[fd].oflags & FLOWFACCMODE) == FLOWFRDONLY) {
pthread_rwlock_unlock(&ai.lock);
return -EPERM;
}
@@ -1527,7 +1511,7 @@ void ipcp_flow_fini(int fd)
{
struct shm_rbuff * rx_rb;
- flow_set_flags(fd, FLOW_O_WRONLY);
+ fccntl(fd, FLOWSFLAGS, FLOWFWRONLY);
pthread_rwlock_rdlock(&ai.lock);
diff --git a/src/lib/frct_pci.c b/src/lib/frct_pci.c
index 4fa9ddc2..e44554f2 100644
--- a/src/lib/frct_pci.c
+++ b/src/lib/frct_pci.c
@@ -30,7 +30,7 @@
#define TYPE_SIZE 1
#define SEQNO_SIZE 8
#define FLAGS_SIZE 1
-#define CONF_FLAGS_SIZE 1
+#define CONF_FLAGS_SIZE sizeof(((struct frct_pci *) NULL)->conf_flags)
#define BASE_SIZE TYPE_SIZE + FLAGS_SIZE + SEQNO_SIZE
#define CONFIG_SIZE CONF_FLAGS_SIZE
diff --git a/src/lib/qos.c b/src/lib/qos.c
index 35e16f97..09866c4e 100644
--- a/src/lib/qos.c
+++ b/src/lib/qos.c
@@ -36,12 +36,6 @@ int qosspec_init(qosspec_t * qs)
qs->availability = 0;
qs->maximum_interruption = UINT32_MAX;
- qs->resource_control = true;
- qs->reliable = false;
- qs->error_check = true;
- qs->ordered = true;
- qs->partial = false;
-
return 0;
}
diff --git a/src/tools/cbr/cbr_server.c b/src/tools/cbr/cbr_server.c
index a2e930e5..b25b09e8 100644
--- a/src/tools/cbr/cbr_server.c
+++ b/src/tools/cbr/cbr_server.c
@@ -22,7 +22,7 @@
#include <ouroboros/dev.h>
#include <ouroboros/time_utils.h>
-#include <ouroboros/fcntl.h>
+#include <ouroboros/fccntl.h>
#include <stdbool.h>
@@ -84,7 +84,7 @@ static void handle_flow(int fd)
alive = iv_start;
ts_add(&iv_start, &intv, &iv_end);
- flow_set_flags(fd, FLOW_O_NONBLOCK);
+ fccntl(fd, FLOWSFLAGS, FLOWFNONBLOCK);
while (!stop) {
clock_gettime(CLOCK_REALTIME, &now);
diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c
index 4ad26d13..df486380 100644
--- a/src/tools/operf/operf_client.c
+++ b/src/tools/operf/operf_client.c
@@ -21,7 +21,7 @@
*/
#include <ouroboros/dev.h>
-#include <ouroboros/fcntl.h>
+#include <ouroboros/fccntl.h>
#include <ouroboros/time_utils.h>
#include <signal.h>
@@ -68,7 +68,7 @@ void * reader(void * o)
int fd = *((int *) o);
int msg_len = 0;
- flow_set_timeout(fd, &timeout);
+ fccntl(fd, FLOWSRCVTIMEO, &timeout);
while ((msg_len = flow_read(fd, buf, OPERF_BUF_SIZE)) != -ETIMEDOUT) {
if (msg_len != client.size) {
diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c
index db0ef199..ca8c0e72 100644
--- a/src/tools/oping/oping_client.c
+++ b/src/tools/oping/oping_client.c
@@ -21,7 +21,7 @@
*/
#include <ouroboros/dev.h>
-#include <ouroboros/fcntl.h>
+#include <ouroboros/fccntl.h>
#include <ouroboros/time_utils.h>
#include <signal.h>
@@ -60,7 +60,7 @@ void * reader(void * o)
double ms = 0;
double d = 0;
- flow_set_timeout(fd, &timeout);
+ fccntl(fd, FLOWSRCVTIMEO, &timeout);
while (client.rcvd != client.count) {
msg_len = flow_read(fd, buf, OPING_BUF_SIZE);
diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c
index 6a535caf..0371f90f 100644
--- a/src/tools/oping/oping_server.c
+++ b/src/tools/oping/oping_server.c
@@ -130,7 +130,7 @@ void * accept_thread(void * o)
server.times[fd] = now;
pthread_mutex_unlock(&server.lock);
- flow_set_flags(fd, FLOW_O_NONBLOCK | FLOW_O_RDWR);
+ fccntl(fd, FLOWSFLAGS, FLOWFNONBLOCK | FLOWFRDWR);
}
return (void *) 0;