From 2de31bfc1a24d6643763f6ef1bbda2948ec46f3a Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 3 Jul 2017 23:36:45 +0200 Subject: [PATCH] Add meshlink_channel_open_ex(). This allows flags to be passed to the underlying UTCP connection, which determines what kind of connection semantics to use. --- src/meshlink++.h | 16 ++++++++++++---- src/meshlink.c | 17 +++++++++++++++-- src/meshlink.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/utcp | 2 +- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/meshlink++.h b/src/meshlink++.h index 30d6ae52..6acfe251 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -89,6 +89,13 @@ namespace meshlink { /// A class describing a MeshLink channel. class channel: public meshlink_channel_t { + public: + static const uint32_t RELIABLE = MESHLINK_CHANNEL_RELIABLE; + static const uint32_t ORDERED = MESHLINK_CHANNEL_ORDERED; + static const uint32_t FRAMED = MESHLINK_CHANNEL_FRAMED; + static const uint32_t DROP_LATE = MESHLINK_CHANNEL_DROP_LATE; + static const uint32_t TCP = MESHLINK_CHANNEL_TCP; + static const uint32_t UDP = MESHLINK_CHANNEL_UDP; }; /// A class describing a MeshLink mesh. @@ -487,11 +494,12 @@ namespace meshlink { * @param cb A pointer to the function which will be called when the remote node sends data to the local node. * @param data A pointer to a buffer containing data to already queue for sending. * @param len The length of the data. + * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. * * @return A handle for the channel, or NULL in case of an error. */ - channel *channel_open(node *node, uint16_t port, channel_receive_cb_t cb, const void *data, size_t len) { - channel *ch = (channel *)meshlink_channel_open(handle, node, port, (meshlink_channel_receive_cb_t)cb, data, len); + channel *channel_open(node *node, uint16_t port, channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags = channel::TCP) { + channel *ch = (channel *)meshlink_channel_open_ex(handle, node, port, (meshlink_channel_receive_cb_t)cb, data, len, flags); meshlink_set_channel_poll_cb(handle, ch, &channel_poll_trampoline); return ch; } @@ -500,8 +508,8 @@ namespace meshlink { * @override * Sets channel_receive_trampoline as cb, which in turn calls this->channel_receive( ... ). */ - channel *channel_open(node *node, uint16_t port, const void *data, size_t len) { - channel *ch = (channel *)meshlink_channel_open(handle, node, port, &channel_receive_trampoline, data, len); + channel *channel_open(node *node, uint16_t port, const void *data, size_t len, uint32_t flags = channel::TCP) { + channel *ch = (channel *)meshlink_channel_open_ex(handle, node, port, &channel_receive_trampoline, data, len, flags); meshlink_set_channel_poll_cb(handle, ch, &channel_poll_trampoline); return ch; } diff --git a/src/meshlink.c b/src/meshlink.c index 0f1e2738..2184c33b 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -2226,7 +2226,7 @@ void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_ac pthread_mutex_unlock(&mesh->mesh_mutex); } -meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) { +meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) { if(!mesh || !node) { meshlink_errno = MESHLINK_EINVAL; return NULL; @@ -2244,7 +2244,7 @@ meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node meshlink_channel_t *channel = xzalloc(sizeof *channel); channel->node = n; channel->receive_cb = cb; - channel->c = utcp_connect(n->utcp, port, channel_recv, channel); + channel->c = utcp_connect_ex(n->utcp, port, channel_recv, channel, flags); if(!channel->c) { meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL; free(channel); @@ -2253,6 +2253,10 @@ meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node return channel; } +meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) { + return meshlink_channel_open_ex(mesh, node, port, cb, data, len, MESHLINK_CHANNEL_TCP); +} + void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) { if(!mesh || !channel) { meshlink_errno = MESHLINK_EINVAL; @@ -2300,6 +2304,15 @@ ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *chann return retval; } +uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel) { + if(!mesh || !channel) { + meshlink_errno = MESHLINK_EINVAL; + return -1; + } + + return channel->c->flags; +} + void update_node_status(meshlink_handle_t *mesh, node_t *n) { if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n); diff --git a/src/meshlink.h b/src/meshlink.h index 7e82cb0d..668d8e71 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -77,6 +77,14 @@ typedef enum { _DEV_CLASS_MAX = 3 } dev_class_t; +/// Channel flags +static const uint32_t MESHLINK_CHANNEL_RELIABLE = 1; // Data is retransmitted when packets are lost. +static const uint32_t MESHLINK_CHANNEL_ORDERED = 2; // Data is delivered in-order to the application. +static const uint32_t MESHLINK_CHANNEL_FRAMED = 4; // Data is delivered in chunks of the same length as data was originally sent. +static const uint32_t MESHLINK_CHANNEL_DROP_LATE = 8; // When packets are reordered, late packets are ignored. +static const uint32_t MESHLINK_CHANNEL_TCP = 3; // Select TCP semantics. +static const uint32_t MESHLINK_CHANNEL_UDP = 0; // Select UDP semantics. + /// A variable holding the last encountered error from MeshLink. /** This is a thread local variable that contains the error code of the most recent error * encountered by a MeshLink API function called in the current thread. @@ -667,6 +675,29 @@ extern void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_ch */ extern void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb); +/// Open a reliable stream channel to another node. +/** This function is called whenever a remote node wants to open a channel to the local node. + * The application then has to decide whether to accept or reject this channel. + * + * This function returns a pointer to a struct meshlink_channel that will be allocated by MeshLink. + * When the application does no longer need to use this channel, it must call meshlink_close() + * to free its resources. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param node The node to which this channel is being initiated. + * @param port The port number the peer wishes to connect to. + * @param cb A pointer to the function which will be called when the remote node sends data to the local node. + * The pointer may be NULL, in which case incoming data is ignored. + * @param data A pointer to a buffer containing data to already queue for sending, or NULL if there is no data to send. + * After meshlink_send() returns, the application is free to overwrite or free this buffer. + * @param len The length of the data, or 0 if there is no data to send. + * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. + * + * @return A handle for the channel, or NULL in case of an error. + * The handle is valid until meshlink_channel_close() is called. + */ +extern meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags); + /// Open a reliable stream channel to another node. /** This function is called whenever a remote node wants to open a channel to the local node. * The application then has to decide whether to accept or reject this channel. @@ -729,6 +760,16 @@ extern void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t * */ extern ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len); +/// Get channel flags. +/** This returns the flags used when opening this channel. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param channel A handle for the channel. + * + * @return The flags set for this channel. + */ +extern uint32_t meshlink_channel_get_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel); + /// Hint that a hostname may be found at an address /** This function indicates to meshlink that the given hostname is likely found * at the given IP address and port. diff --git a/src/utcp b/src/utcp index a7ec88e6..5ded6337 160000 --- a/src/utcp +++ b/src/utcp @@ -1 +1 @@ -Subproject commit a7ec88e641e14ca115fece6d1ea0e6c43144853f +Subproject commit 5ded633782709710c42648c71154d6062e83b7a6 -- 2.39.2