+ /// Transmit data on a channel
+ /** This queues data to send to the remote node.
+ *
+ * @param channel A handle for the channel.
+ * @param data A pointer to a buffer containing data sent by the source.
+ * @param len The length of the data.
+ *
+ * @return The amount of data that was queued, which can be less than len, or a negative value in case of an error.
+ */
+ ssize_t channel_send(channel *channel, void *data, size_t len) {
+ return meshlink_channel_send(handle, channel, data, len);
+ }
+
+ /// Enable or disable zeroconf discovery of local peers
+ /** This controls whether zeroconf discovery using the Catta library will be
+ * enabled to search for peers on the local network. By default, it is enabled.
+ *
+ * @param enable Set to true to enable discovery, false to disable.
+ */
+ void enable_discovery(bool enable = true) {
+ meshlink_enable_discovery(handle, enable);
+ }
+
+private:
+ // non-copyable:
+ mesh(const mesh &) /* TODO: C++11: = delete */;
+ void operator=(const mesh &) /* TODO: C++11: = delete */ ;
+
+ /// static callback trampolines:
+ static void receive_trampoline(meshlink_handle_t *handle, meshlink_node_t *source, const void *data, size_t length) {
+ if(!(handle->priv)) {
+ return;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ that->receive(static_cast<node *>(source), data, length);
+ }
+
+ static void node_status_trampoline(meshlink_handle_t *handle, meshlink_node_t *peer, bool reachable) {
+ if(!(handle->priv)) {
+ return;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ that->node_status(static_cast<node *>(peer), reachable);
+ }
+
+ static void log_trampoline(meshlink_handle_t *handle, log_level_t level, const char *message) {
+ if(!(handle->priv)) {
+ return;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ that->log(level, message);
+ }
+
+ static bool channel_accept_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, uint16_t port, const void *data, size_t len) {
+ if(!(handle->priv)) {
+ return false;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ bool accepted = that->channel_accept(static_cast<meshlink::channel *>(channel), port, data, len);
+
+ if(accepted) {
+ meshlink_set_channel_receive_cb(handle, channel, &channel_receive_trampoline);
+ meshlink_set_channel_poll_cb(handle, channel, &channel_poll_trampoline);
+ }
+
+ return accepted;
+ }
+
+ static void channel_receive_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, const void *data, size_t len) {
+ if(!(handle->priv)) {
+ return;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ that->channel_receive(static_cast<meshlink::channel *>(channel), data, len);
+ }
+
+ static void channel_poll_trampoline(meshlink_handle_t *handle, meshlink_channel *channel, size_t len) {
+ if(!(handle->priv)) {
+ return;
+ }
+
+ meshlink::mesh *that = static_cast<mesh *>(handle->priv);
+ that->channel_poll(static_cast<meshlink::channel *>(channel), len);
+ }
+
+ meshlink_handle_t *handle;
+};
+
+static inline const char *strerror(errno_t err = meshlink_errno) {
+ return meshlink_strerror(err);
+}
+
+/// Destroy a MeshLink instance.
+/** This function remove all configuration files of a MeshLink instance. It should only be called when the application
+ * does not have an open handle to this instance. Afterwards, a call to meshlink_open() will create a completely
+ * new instance.
+ *
+ * @param confbase The directory in which MeshLink stores its configuration files.
+ * After the function returns, the application is free to overwrite or free @a confbase @a.
+ *
+ * @return This function will return true if the MeshLink instance was succesfully destroyed, false otherwise.
+ */
+static inline bool destroy(const char *confbase) {
+ return meshlink_destroy(confbase);
+}