free(mesh->confbase);
free(mesh->config_key);
ecdsa_free(mesh->private_key);
- pthread_mutex_destroy(&(mesh->mesh_mutex));
main_config_unlock(mesh);
+ pthread_mutex_unlock(&mesh->mesh_mutex);
+ pthread_mutex_destroy(&mesh->mesh_mutex);
+
memset(mesh, 0, sizeof(*mesh));
free(mesh);
}
}
+void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) {
+ if(!mesh) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ pthread_mutex_lock(&(mesh->mesh_mutex));
+ mesh->error_cb = cb;
+ pthread_mutex_unlock(&(mesh->mesh_mutex));
+}
+
bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
meshlink_packethdr_t *hdr;
return utcp_get_recvq(channel->c);
}
+void meshlink_set_node_channel_timeout(meshlink_handle_t *mesh, meshlink_node_t *node, int timeout) {
+ if(!mesh || !node) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ node_t *n = (node_t *)node;
+
+ pthread_mutex_lock(&mesh->mesh_mutex);
+
+ if(!n->utcp) {
+ n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
+ }
+
+ utcp_set_user_timeout(n->utcp, timeout);
+
+ pthread_mutex_unlock(&mesh->mesh_mutex);
+}
+
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);
retry(mesh);
}
+void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t meshlink_errno) {
+ // We should only call the callback function if we are in the background thread.
+ if(!mesh->error_cb) {
+ return;
+ }
+
+ if(!mesh->threadstarted) {
+ return;
+ }
+
+ if(mesh->thread == pthread_self()) {
+ mesh->error_cb(mesh, meshlink_errno);
+ }
+}
+
+
static void __attribute__((constructor)) meshlink_init(void) {
crypto_init();
}