From 55010e8cd9fad4996db774aab3d578b431f9ee73 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 31 Jan 2019 22:38:48 +0100 Subject: [PATCH] Add API functions to query nodes by device class. --- src/meshlink.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/meshlink.h | 30 ++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/meshlink.c b/src/meshlink.c index 52017623..815acdea 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1847,6 +1847,68 @@ meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_ return result; } +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 || ((int)devclass < 0) || (devclass > _DEV_CLASS_MAX) || !nmemb) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + meshlink_node_t **result; + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + *nmemb = 0; + + for splay_each(node_t, n, mesh->nodes) { + if(n->devclass == devclass) { + *nmemb = *nmemb + 1; + } + } + + if(*nmemb == 0) { + free(nodes); + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return NULL; + } + + result = realloc(nodes, *nmemb * sizeof(*nodes)); + + if(result) { + meshlink_node_t **p = result; + + for splay_each(node_t, n, mesh->nodes) { + if(n->devclass == devclass) { + *p++ = (meshlink_node_t *)n; + } + } + } else { + *nmemb = 0; + free(nodes); + meshlink_errno = MESHLINK_ENOMEM; + } + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return result; +} + +dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node) { + if(!mesh || !node) { + meshlink_errno = MESHLINK_EINVAL; + return -1; + } + + dev_class_t devclass; + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + devclass = ((node_t *)node)->devclass; + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return devclass; +} + bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) { if(!mesh || !data || !len || !signature || !siglen) { meshlink_errno = MESHLINK_EINVAL; diff --git a/src/meshlink.h b/src/meshlink.h index 968d3442..35b9bd64 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -469,6 +469,36 @@ extern meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlin */ extern bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen); +/// Get the list of all nodes by device class. +/** This function returns a list with handles for all the nodes that matches with the given @a devclass @a . + * + * @param mesh A handle which represents an instance of MeshLink. + * @param devclass Device class of the nodes for which the list has to be obtained. + * @param nodes A pointer to a previously allocated array of pointers to meshlink_node_t, or NULL in which case MeshLink will allocate a new array. + * The application can supply an array it allocated itself with malloc, or the return value from the previous call to this function (which is the preferred way). + * The application is allowed to call free() on the array whenever it wishes. + * The pointers in the array are valid until meshlink_close() is called. + * @param nmemb A pointer to a variable holding the number of nodes with the same @a device class @a that are stored in the array. + * In case the @a nodes @a argument is not NULL, MeshLink might call realloc() on the array to change its size. + * The contents of this variable will be changed to reflect the new size of the array. + * + * @return A pointer to an array containing pointers to all known nodes of the given device class, or NULL in case of an error. + * If the @a nodes @a argument was not NULL, then the return value can either be the same value or a different value. + * If it is a new value, the old value of @a nodes @a should not be used anymore. + * If the new value is NULL, then the old array will have been freed by MeshLink. + */ +extern 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); + +/// Get the node's device class. +/** This function returns the device class of the given node. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param node A pointer to a meshlink_node_t describing the node. + * + * @return This function returns the device class of the @a node @a , or -1 in case of an error. + */ +extern dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node); + /// Verify the signature generated by another node of a piece of data. /** This function verifies the signature that another node generated for a piece of data. * -- 2.39.5