aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/Makefile.am20
-rw-r--r--examples/lapd-over-datagram-network.c (renamed from examples/lapd-over-stream-server.c)80
-rw-r--r--examples/lapd-over-datagram-user.c (renamed from examples/lapd-over-stream-client.c)45
-rw-r--r--include/osmocom/netif/Makefile.am3
-rw-r--r--include/osmocom/netif/datagram.h47
-rw-r--r--src/Makefile.am3
-rw-r--r--src/datagram.c354
7 files changed, 469 insertions, 83 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 981128b..c1759e2 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -2,15 +2,15 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS)
AM_LDFLAGS = $(COVERAGE_LDFLAGS)
-noinst_PROGRAMS = lapd-over-stream-client \
- lapd-over-stream-server
+noinst_PROGRAMS = lapd-over-datagram-user \
+ lapd-over-datagram-network
-lapd_over_stream_client_SOURCES = lapd-over-stream-client.c
-lapd_over_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \
- $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOABIS_LIBS)
+lapd_over_datagram_user_SOURCES = lapd-over-datagram-user.c
+lapd_over_datagram_user_LDADD = $(top_builddir)/src/libosmonetif.la \
+ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOABIS_LIBS)
-lapd_over_stream_server_SOURCES = lapd-over-stream-server.c
-lapd_over_stream_server_LDADD = $(top_builddir)/src/libosmonetif.la \
- $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOABIS_LIBS)
+lapd_over_datagram_network_SOURCES = lapd-over-datagram-network.c
+lapd_over_datagram_network_LDADD = $(top_builddir)/src/libosmonetif.la \
+ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOABIS_LIBS)
diff --git a/examples/lapd-over-stream-server.c b/examples/lapd-over-datagram-network.c
index 8d06f62..a0c8ac9 100644
--- a/examples/lapd-over-stream-server.c
+++ b/examples/lapd-over-datagram-network.c
@@ -1,4 +1,4 @@
-/* LAPD over stream (network-mode/server) example. */
+/* LAPD over datagram network-mode example. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -8,10 +8,11 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
+#include <osmocom/core/select.h>
#include <osmocom/abis/lapd.h>
-#include <osmocom/netif/stream.h>
+#include <osmocom/netif/datagram.h>
static void *tall_test;
@@ -32,7 +33,7 @@ const struct log_info lapd_test_log_info = {
.num_cat = ARRAY_SIZE(lapd_test_cat),
};
-static struct stream_server_link *server;
+static struct datagram_conn *conn;
static struct lapd_instance *lapd;
static int sapi = 63, tei = 0;
@@ -43,11 +44,11 @@ void sighandler(int foo)
exit(EXIT_SUCCESS);
}
-int read_cb(struct stream_server_conn *conn, struct msgb *msg)
+int read_cb(struct datagram_server_conn *conn, struct msgb *msg)
{
int error;
- LOGP(DLINP, LOGL_NOTICE, "received message from stream\n");
+ LOGP(DLINP, LOGL_NOTICE, "received message from datagram\n");
if (lapd_receive(lapd, msg, &error) < 0) {
LOGP(DLINP, LOGL_ERROR, "lapd_receive returned error!\n");
@@ -58,10 +59,10 @@ int read_cb(struct stream_server_conn *conn, struct msgb *msg)
void lapd_tx_cb(struct msgb *msg, void *cbdata)
{
- struct stream_server_conn *conn = cbdata;
+ struct datagram_conn *conn = cbdata;
- LOGP(DLINP, LOGL_NOTICE, "sending message over stream\n");
- stream_server_conn_send(conn, msg);
+ LOGP(DLINP, LOGL_NOTICE, "sending message over datagram\n");
+ datagram_conn_send(conn, msg);
}
void lapd_rx_cb(struct osmo_dlsap_prim *dp, uint8_t tei, uint8_t sapi,
@@ -95,37 +96,6 @@ void lapd_rx_cb(struct osmo_dlsap_prim *dp, uint8_t tei, uint8_t sapi,
}
}
-static int accept_cb(struct stream_server_link *server, int fd)
-{
- struct stream_server_conn *conn;
- int teip;
-
- conn = stream_server_conn_create(tall_test, server, fd, read_cb,
- NULL, NULL);
- if (conn == NULL) {
- LOGP(DLINP, LOGL_ERROR, "error in lapd_receive\n");
- return -1;
- }
-
- /*
- * initialize LAPD stuff.
- */
-
- lapd = lapd_instance_alloc(1, lapd_tx_cb, conn, lapd_rx_cb, conn,
- &lapd_profile_sat);
- if (lapd == NULL) {
- LOGP(DLINP, LOGL_ERROR, "cannot allocate instance\n");
- exit(EXIT_FAILURE);
- }
-
- teip = lapd_tei_alloc(lapd, tei);
- if (teip == 0) {
- LOGP(DLINP, LOGL_ERROR, "cannot assign TEI\n");
- exit(EXIT_FAILURE);
- }
- return 0;
-}
-
static int kbd_cb(struct osmo_fd *fd, unsigned int what)
{
char buf[1024];
@@ -154,6 +124,7 @@ static int kbd_cb(struct osmo_fd *fd, unsigned int what)
int main(void)
{
struct osmo_fd *kbd_ofd;
+ int teip;
tall_test = talloc_named_const(NULL, 1, "lapd_test");
@@ -161,19 +132,34 @@ int main(void)
log_set_log_level(osmo_stderr_target, 1);
/*
- * initialize stream server.
+ * initialize datagram server.
*/
- server = stream_server_link_create(tall_test);
- if (server == NULL) {
+ conn = datagram_conn_create(tall_test);
+ if (conn == NULL) {
fprintf(stderr, "cannot create client\n");
exit(EXIT_FAILURE);
}
- stream_server_link_set_addr(server, "127.0.0.1");
- stream_server_link_set_port(server, 10000);
- stream_server_link_set_accept_cb(server, accept_cb);
+ datagram_conn_set_local_addr(conn, "127.0.0.1");
+ datagram_conn_set_local_port(conn, 10001);
+ datagram_conn_set_remote_addr(conn, "127.0.0.1");
+ datagram_conn_set_remote_port(conn, 10000);
+ datagram_conn_set_read_cb(conn, read_cb);
+
+ lapd = lapd_instance_alloc(1, lapd_tx_cb, conn, lapd_rx_cb, conn,
+ &lapd_profile_sat);
+ if (lapd == NULL) {
+ LOGP(DLINP, LOGL_ERROR, "cannot allocate instance\n");
+ exit(EXIT_FAILURE);
+ }
+
+ teip = lapd_tei_alloc(lapd, tei);
+ if (teip == 0) {
+ LOGP(DLINP, LOGL_ERROR, "cannot assign TEI\n");
+ exit(EXIT_FAILURE);
+ }
- if (stream_server_link_open(server) < 0) {
+ if (datagram_conn_open(conn) < 0) {
fprintf(stderr, "cannot open client\n");
exit(EXIT_FAILURE);
}
@@ -185,7 +171,7 @@ int main(void)
}
kbd_ofd->fd = STDIN_FILENO;
kbd_ofd->when = BSC_FD_READ;
- kbd_ofd->data = server;
+ kbd_ofd->data = conn;
kbd_ofd->cb = kbd_cb;
osmo_fd_register(kbd_ofd);
diff --git a/examples/lapd-over-stream-client.c b/examples/lapd-over-datagram-user.c
index 1525b7c..2e6e02e 100644
--- a/examples/lapd-over-stream-client.c
+++ b/examples/lapd-over-datagram-user.c
@@ -1,4 +1,4 @@
-/* LAPD over stream (user-mode/client) example. */
+/* LAPD over datagram user-mode example. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -8,10 +8,11 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
+#include <osmocom/core/select.h>
#include <osmocom/abis/lapd.h>
-#include <osmocom/netif/stream.h>
+#include <osmocom/netif/datagram.h>
#define DLAPDTEST 0
@@ -30,7 +31,7 @@ const struct log_info lapd_test_log_info = {
.num_cat = ARRAY_SIZE(lapd_test_cat),
};
-static struct stream_client_conn *conn;
+static struct datagram_conn *conn;
static struct lapd_instance *lapd;
static int sapi = 63, tei = 0;
@@ -42,21 +43,11 @@ void sighandler(int foo)
exit(EXIT_SUCCESS);
}
-static int connect_cb(struct stream_client_conn *conn)
-{
- LOGP(DLINP, LOGL_NOTICE, "connected\n");
- if (lapd_sap_start(lapd, tei, sapi) < 0) {
- LOGP(DLINP, LOGL_ERROR, "cannot start user-side LAPD\n");
- exit(EXIT_FAILURE);
- }
- return 0;
-}
-
-static int read_cb(struct stream_client_conn *conn, struct msgb *msg)
+static int read_cb(struct datagram_server_conn *conn, struct msgb *msg)
{
int error;
- LOGP(DLINP, LOGL_NOTICE, "received message from stream\n");
+ LOGP(DLINP, LOGL_NOTICE, "received message from datagram\n");
if (lapd_receive(lapd, msg, &error) < 0) {
LOGP(DLINP, LOGL_ERROR, "lapd_receive returned error!\n");
@@ -69,8 +60,8 @@ static void *tall_test;
void lapd_tx_cb(struct msgb *msg, void *cbdata)
{
- LOGP(DLINP, LOGL_NOTICE, "sending message over stream\n");
- stream_client_conn_send(conn, msg);
+ LOGP(DLINP, LOGL_NOTICE, "sending message over datagram\n");
+ datagram_conn_send(conn, msg);
}
void lapd_rx_cb(struct osmo_dlsap_prim *dp, uint8_t tei, uint8_t sapi,
@@ -150,24 +141,30 @@ int main(void)
}
/*
- * initialize stream client.
+ * initialize datagram socket.
*/
- conn = stream_client_conn_create(tall_test);
+ conn = datagram_conn_create(tall_test);
if (conn == NULL) {
fprintf(stderr, "cannot create client\n");
exit(EXIT_FAILURE);
}
- stream_client_conn_set_addr(conn, "127.0.0.1");
- stream_client_conn_set_port(conn, 10000);
- stream_client_conn_set_connect_cb(conn, connect_cb);
- stream_client_conn_set_read_cb(conn, read_cb);
+ datagram_conn_set_local_addr(conn, "127.0.0.1");
+ datagram_conn_set_local_port(conn, 10000);
+ datagram_conn_set_remote_addr(conn, "127.0.0.1");
+ datagram_conn_set_remote_port(conn, 10001);
+ datagram_conn_set_read_cb(conn, read_cb);
- if (stream_client_conn_open(conn) < 0) {
+ if (datagram_conn_open(conn) < 0) {
fprintf(stderr, "cannot open client\n");
exit(EXIT_FAILURE);
}
+ if (lapd_sap_start(lapd, tei, sapi) < 0) {
+ LOGP(DLINP, LOGL_ERROR, "cannot start user-side LAPD\n");
+ exit(EXIT_FAILURE);
+ }
+
kbd_ofd = talloc_zero(tall_test, struct osmo_fd);
if (!kbd_ofd) {
LOGP(DLAPDTEST, LOGL_ERROR, "OOM\n");
diff --git a/include/osmocom/netif/Makefile.am b/include/osmocom/netif/Makefile.am
index 8b68362..afab204 100644
--- a/include/osmocom/netif/Makefile.am
+++ b/include/osmocom/netif/Makefile.am
@@ -1,3 +1,4 @@
-osmonetif_HEADERS = stream.h
+osmonetif_HEADERS = datagram.h \
+ stream.h
osmonetifdir = $(includedir)/osmocom/netif
diff --git a/include/osmocom/netif/datagram.h b/include/osmocom/netif/datagram.h
new file mode 100644
index 0000000..abda79b
--- /dev/null
+++ b/include/osmocom/netif/datagram.h
@@ -0,0 +1,47 @@
+#ifndef _OSMO_DGRAM_H_
+#define _OSMO_DGRAM_H_
+
+struct datagram_client_conn;
+
+struct datagram_client_conn *datagram_client_conn_create(void *ctx);
+void datagram_client_conn_destroy(struct datagram_client_conn *conn);
+
+void datagram_client_conn_set_addr(struct datagram_client_conn *conn, const char *addr);
+void datagram_client_conn_set_port(struct datagram_client_conn *conn, uint16_t port);
+void datagram_client_conn_set_data(struct datagram_client_conn *conn, void *data);
+
+int datagram_client_conn_open(struct datagram_client_conn *conn);
+void datagram_client_conn_close(struct datagram_client_conn *conn);
+
+void datagram_client_conn_send(struct datagram_client_conn *conn, struct msgb *msg);
+
+struct datagram_server_conn;
+
+struct datagram_server_conn *datagram_server_conn_create(void *ctx);
+
+void datagram_server_conn_set_addr(struct datagram_server_conn *conn, const char *addr);
+void datagram_server_conn_set_port(struct datagram_server_conn *conn, uint16_t port);
+void datagram_server_conn_set_read_cb(struct datagram_server_conn *conn, int (*read_cb)(struct datagram_server_conn *conn, struct msgb *msg));
+void datagram_server_conn_destroy(struct datagram_server_conn *conn);
+
+int datagram_server_conn_open(struct datagram_server_conn *conn);
+void datagram_server_conn_close(struct datagram_server_conn *conn);
+
+struct datagram_conn;
+
+struct datagram_conn *datagram_conn_create(void *ctx);
+void datagram_conn_destroy(struct datagram_conn *conn);
+
+int datagram_conn_open(struct datagram_conn *conn);
+void datagram_conn_close(struct datagram_conn *conn);
+
+void datagram_conn_set_local_addr(struct datagram_conn *conn, const char *addr);
+void datagram_conn_set_remote_addr(struct datagram_conn *conn, const char *addr);
+void datagram_conn_set_local_port(struct datagram_conn *conn, uint16_t port);
+void datagram_conn_set_remote_port(struct datagram_conn *conn, uint16_t port);
+void datagram_conn_set_read_cb(struct datagram_conn *conn, int (*read_cb)(struct datagram_server_conn *conn, struct msgb *msg));
+void datagram_conn_set_data(struct datagram_client_conn *conn, void *data);
+
+void datagram_conn_send(struct datagram_conn *conn, struct msgb *msg);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 30e1e72..bf2d60a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,4 +8,5 @@ AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAG
lib_LTLIBRARIES = libosmonetif.la
-libosmonetif_la_SOURCES = stream.c
+libosmonetif_la_SOURCES = datagram.c \
+ stream.c
diff --git a/src/datagram.c b/src/datagram.c
new file mode 100644
index 0000000..cd09025
--- /dev/null
+++ b/src/datagram.c
@@ -0,0 +1,354 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <sys/fcntl.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/select.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/socket.h>
+
+#include <osmocom/netif/datagram.h>
+
+/*
+ * Client side.
+ */
+
+struct datagram_client_conn {
+ struct osmo_fd ofd;
+ struct llist_head tx_queue;
+ const char *addr;
+ uint16_t port;
+ int (*write_cb)(struct datagram_client_conn *conn);
+ void *data;
+};
+
+void datagram_client_conn_close(struct datagram_client_conn *conn)
+{
+ osmo_fd_unregister(&conn->ofd);
+ close(conn->ofd.fd);
+}
+
+static int datagram_client_write(struct datagram_client_conn *conn)
+{
+ struct msgb *msg;
+ struct llist_head *lh;
+ int ret;
+
+ LOGP(DLINP, LOGL_DEBUG, "sending data\n");
+
+ if (llist_empty(&conn->tx_queue)) {
+ conn->ofd.when &= ~BSC_FD_WRITE;
+ return 0;
+ }
+ lh = conn->tx_queue.next;
+ llist_del(lh);
+ msg = llist_entry(lh, struct msgb, list);
+
+ ret = send(conn->ofd.fd, msg->data, msg->len, 0);
+ if (ret < 0) {
+ LOGP(DLINP, LOGL_ERROR, "error to send (%s)\n",
+ strerror(errno));
+ }
+ msgb_free(msg);
+ return 0;
+}
+
+static int datagram_client_fd_cb(struct osmo_fd *ofd, unsigned int what)
+{
+ struct datagram_client_conn *conn = ofd->data;
+
+ if (what & BSC_FD_WRITE) {
+ LOGP(DLINP, LOGL_DEBUG, "connected write\n");
+ datagram_client_write(conn);
+ }
+ return 0;
+}
+
+struct datagram_client_conn *datagram_client_conn_create(void *ctx)
+{
+ struct datagram_client_conn *conn;
+
+ conn = talloc_zero(ctx, struct datagram_client_conn);
+ if (!conn)
+ return NULL;
+
+ conn->ofd.when |= BSC_FD_READ;
+ conn->ofd.priv_nr = 0; /* XXX */
+ conn->ofd.cb = datagram_client_fd_cb;
+ conn->ofd.data = conn;
+ INIT_LLIST_HEAD(&conn->tx_queue);
+
+ return conn;
+}
+
+void
+datagram_client_conn_set_addr(struct datagram_client_conn *conn, const char *addr)
+{
+ conn->addr = talloc_strdup(conn, addr);
+}
+
+void
+datagram_client_conn_set_port(struct datagram_client_conn *conn, uint16_t port)
+{
+ conn->port = port;
+}
+
+void
+datagram_client_conn_set_data(struct datagram_client_conn *conn, void *data)
+{
+ conn->data = data;
+}
+
+void datagram_client_conn_destroy(struct datagram_client_conn *conn)
+{
+ talloc_free(conn);
+}
+
+int datagram_client_conn_open(struct datagram_client_conn *conn)
+{
+ int ret;
+
+ ret = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+ conn->addr, conn->port,
+ OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK);
+ if (ret < 0) {
+ if (errno != EINPROGRESS)
+ return ret;
+ }
+ conn->ofd.fd = ret;
+ if (osmo_fd_register(&conn->ofd) < 0) {
+ close(ret);
+ return -EIO;
+ }
+ return 0;
+}
+
+void datagram_client_conn_send(struct datagram_client_conn *conn, struct msgb *msg)
+{
+ msgb_enqueue(&conn->tx_queue, msg);
+ conn->ofd.when |= BSC_FD_WRITE;
+}
+
+/*
+ * Server side.
+ */
+
+struct datagram_server_conn {
+ struct osmo_fd ofd;
+ const char *addr;
+ uint16_t port;
+ int (*cb)(struct datagram_server_conn *conn, struct msgb *msg);
+ void *data;
+};
+
+static void datagram_server_conn_read(struct datagram_server_conn *conn)
+{
+ struct msgb *msg;
+ int ret;
+
+ LOGP(DLINP, LOGL_DEBUG, "message received\n");
+
+ msg = msgb_alloc(1200, "LAPD/client");
+ if (!msg) {
+ LOGP(DLINP, LOGL_ERROR, "cannot allocate room for message\n");
+ return;
+ }
+ ret = recv(conn->ofd.fd, msg->data, msg->data_len, 0);
+ if (ret < 0) {
+ if (errno == EPIPE || errno == ECONNRESET) {
+ LOGP(DLINP, LOGL_ERROR, "lost connection with server\n");
+ }
+ datagram_server_conn_destroy(conn);
+ return;
+ } else if (ret == 0) {
+ LOGP(DLINP, LOGL_ERROR, "connection closed with server\n");
+ datagram_server_conn_destroy(conn);
+ return;
+ }
+ msgb_put(msg, ret);
+ LOGP(DLINP, LOGL_NOTICE, "received %d bytes from client\n", ret);
+ if (conn->cb)
+ conn->cb(conn, msg);
+
+ return;
+}
+
+static int datagram_server_conn_cb(struct osmo_fd *ofd, unsigned int what)
+{
+ struct datagram_server_conn *conn = ofd->data;
+
+ LOGP(DLINP, LOGL_DEBUG, "connected read/write\n");
+ if (what & BSC_FD_READ)
+ datagram_server_conn_read(conn);
+
+ return 0;
+}
+
+struct datagram_server_conn *datagram_server_conn_create(void *ctx)
+{
+ struct datagram_server_conn *conn;
+
+ conn = talloc_zero(ctx, struct datagram_server_conn);
+ if (!conn)
+ return NULL;
+
+ conn->ofd.when |= BSC_FD_READ;
+ conn->ofd.cb = datagram_server_conn_cb;
+ conn->ofd.data = conn;
+
+ return conn;
+}
+
+void datagram_server_conn_set_addr(struct datagram_server_conn *conn, const char *addr)
+{
+ conn->addr = talloc_strdup(conn, addr);
+}
+
+void datagram_server_conn_set_port(struct datagram_server_conn *conn, uint16_t port)
+{
+ conn->port = port;
+}
+
+void datagram_server_conn_set_read_cb(struct datagram_server_conn *conn,
+ int (*read_cb)(struct datagram_server_conn *conn, struct msgb *msg))
+{
+ conn->cb = read_cb;
+}
+
+void datagram_server_conn_destroy(struct datagram_server_conn *conn)
+{
+ talloc_free(conn);
+}
+
+int datagram_server_conn_open(struct datagram_server_conn *conn)
+{
+ int ret;
+
+ ret = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+ conn->addr, conn->port, OSMO_SOCK_F_BIND);
+ if (ret < 0)
+ return ret;
+
+ conn->ofd.fd = ret;
+ if (osmo_fd_register(&conn->ofd) < 0) {
+ close(ret);
+ return -EIO;
+ }
+ return 0;
+}
+
+void datagram_server_conn_close(struct datagram_server_conn *conn)
+{
+ osmo_fd_unregister(&conn->ofd);
+ close(conn->ofd.fd);
+}
+
+/*
+ * Client+Server (bidirectional communications).
+ */
+
+struct datagram_conn {
+ struct datagram_server_conn *server;
+ struct datagram_client_conn *client;
+ void *data;
+};
+
+struct datagram_conn *datagram_conn_create(void *ctx)
+{
+ struct datagram_conn *conn;
+
+ conn = talloc_zero(ctx, struct datagram_conn);
+ if (!conn)
+ return NULL;
+
+ conn->server = datagram_server_conn_create(ctx);
+ if (conn->server == NULL)
+ return NULL;
+
+ conn->client = datagram_client_conn_create(ctx);
+ if (conn->client == NULL) {
+ datagram_server_conn_destroy(conn->server);
+ return NULL;
+ }
+
+ return conn;
+}
+
+void datagram_conn_destroy(struct datagram_conn *conn)
+{
+ datagram_server_conn_destroy(conn->server);
+ datagram_client_conn_destroy(conn->client);
+}
+
+void
+datagram_conn_set_local_addr(struct datagram_conn *conn, const char *addr)
+{
+ datagram_server_conn_set_addr(conn->server, addr);
+}
+
+void
+datagram_conn_set_remote_addr(struct datagram_conn *conn, const char *addr)
+{
+ datagram_client_conn_set_addr(conn->client, addr);
+}
+
+void
+datagram_conn_set_local_port(struct datagram_conn *conn, uint16_t port)
+{
+ datagram_server_conn_set_port(conn->server, port);
+}
+
+void
+datagram_conn_set_remote_port(struct datagram_conn *conn, uint16_t port)
+{
+ datagram_client_conn_set_port(conn->client, port);
+}
+
+void datagram_conn_set_read_cb(struct datagram_conn *conn,
+ int (*read_cb)(struct datagram_server_conn *conn, struct msgb *msg))
+{
+ conn->server->cb = read_cb;
+}
+
+void
+datagram_conn_set_data(struct datagram_client_conn *conn, void *data)
+{
+ conn->data = data;
+}
+
+int datagram_conn_open(struct datagram_conn *conn)
+{
+ int ret;
+
+ ret = datagram_server_conn_open(conn->server);
+ if (ret < 0)
+ return ret;
+
+ ret = datagram_client_conn_open(conn->client);
+ if (ret < 0) {
+ datagram_server_conn_close(conn->server);
+ return ret;
+ }
+ return ret;
+}
+
+void datagram_conn_close(struct datagram_conn *conn)
+{
+ datagram_server_conn_close(conn->server);
+ datagram_client_conn_close(conn->client);
+}
+
+void datagram_conn_send(struct datagram_conn *conn, struct msgb *msg)
+{
+ datagram_client_conn_send(conn->client, msg);
+}