pthread_cond_wait(&mesh->cond, &mesh->mutex);
mesh->threadstarted = true;
+ mesh->self->last_reachable = time(NULL);
+ mesh->self->status.dirty = true;
pthread_mutex_unlock(&mesh->mutex);
return true;
pthread_mutex_lock(&mesh->mutex);
logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
+ if(mesh->self) {
+ mesh->self->last_unreachable = time(NULL);
+ mesh->self->status.dirty = true;
+ }
+
// Shut down the main thread
event_loop_stop(&mesh->loop);
return false;
}
+struct time_range {
+ time_t start;
+ time_t end;
+};
+
+static bool search_node_by_last_reachable(const node_t *node, const void *condition) {
+ const struct time_range *range = condition;
+ time_t start = node->last_reachable;
+ time_t end = node->last_unreachable;
+
+ if(end < start) {
+ end = time(NULL);
+
+ if(end < start) {
+ start = end;
+ }
+ }
+
+ if(range->end >= range->start) {
+ return start <= range->end && end >= range->start;
+ } else {
+ return start > range->start || end < range->end;
+ }
+}
+
meshlink_node_t **meshlink_get_all_nodes_by_dev_class(meshlink_handle_t *mesh, dev_class_t devclass, meshlink_node_t **nodes, size_t *nmemb) {
if(!mesh || devclass < 0 || devclass >= DEV_CLASS_COUNT || !nmemb) {
meshlink_errno = MESHLINK_EINVAL;
return meshlink_get_all_nodes_by_condition(mesh, submesh, nodes, nmemb, search_node_by_submesh);
}
+meshlink_node_t **meshlink_get_all_nodes_by_last_reachable(meshlink_handle_t *mesh, time_t start, time_t end, meshlink_node_t **nodes, size_t *nmemb) {
+ if(!mesh || !nmemb) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }
+
+ struct time_range range = {start, end};
+
+ return meshlink_get_all_nodes_by_condition(mesh, &range, nodes, nmemb, search_node_by_last_reachable);
+}
+
dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) {
if(!mesh || !node) {
meshlink_errno = MESHLINK_EINVAL;
packmsg_add_sockaddr(&out, &mesh->self->recent[i]);
}
+ packmsg_add_int64(&out, 0);
+ packmsg_add_int64(&out, 0);
+
pthread_mutex_unlock(&mesh->mutex);
if(!packmsg_output_ok(&out)) {