]> git.meshlink.io Git - meshlink/blobdiff - src/submesh.c
Avoid allocating packet buffers unnecessarily.
[meshlink] / src / submesh.c
index 428ab5b61693f861400375765df240083079a13a..4af2be075401b6684f1ec1aea7bbd16d52b24f60 100644 (file)
@@ -1,6 +1,6 @@
 /*
-    node.c -- node tree management
-    Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>,
+    submesh.c -- submesh management
+    Copyright (C) 2019 Guus Sliepen <guus@meshlink.io>,
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include "splay_tree.h"
 #include "utils.h"
 #include "xalloc.h"
+#include "protocol.h"
+
+static submesh_t *new_submesh(void) {
+       return xzalloc(sizeof(submesh_t));
+}
+
+static void free_submesh(submesh_t *s) {
+       free(s->name);
+       free(s);
+}
 
 void init_submeshes(meshlink_handle_t *mesh) {
+       assert(!mesh->submeshes);
        mesh->submeshes = list_alloc((list_action_t)free_submesh);
 }
 
 void exit_submeshes(meshlink_handle_t *mesh) {
-       list_delete_list(mesh->submeshes);
+       if(mesh->submeshes) {
+               list_delete_list(mesh->submeshes);
+       }
+
        mesh->submeshes = NULL;
 }
 
-submesh_t *new_submesh(void) {
-       submesh_t *s = xzalloc(sizeof(*s));
-
-       s->name = NULL;
-       s->priv = NULL;
+static submesh_t *submesh_add(meshlink_handle_t *mesh, const char *submesh) {
+       assert(submesh);
 
+       submesh_t *s = new_submesh();
+       s->name = xstrdup(submesh);
+       list_insert_tail(mesh->submeshes, (void *)s);
        return s;
 }
 
-void free_submesh(submesh_t *s) {
-       if(s->name) {
-               free(s->name);
+submesh_t *create_submesh(meshlink_handle_t *mesh, const char *submesh) {
+       assert(submesh);
+
+       if(0 == strcmp(submesh, CORE_MESH)) {
+               logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
        }
 
-       free(s);
-}
+       if(!check_id(submesh)) {
+               logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
 
-void submesh_add(meshlink_handle_t *mesh, submesh_t *s) {
-       s->mesh = mesh;
-       list_insert_tail(mesh->submeshes, (void *)s);
+       if(lookup_submesh(mesh, submesh)) {
+               logger(NULL, MESHLINK_ERROR, "SubMesh Already exists!\n");
+               meshlink_errno = MESHLINK_EEXIST;
+               return NULL;
+       }
+
+       return submesh_add(mesh, submesh);
 }
 
-void submesh_del(meshlink_handle_t *mesh, submesh_t *s) {
-       list_delete(mesh->submeshes, (void *)s);
+submesh_t *lookup_or_create_submesh(meshlink_handle_t *mesh, const char *submesh) {
+       assert(submesh);
+
+       if(0 == strcmp(submesh, CORE_MESH)) {
+               logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       if(!check_id(submesh)) {
+               logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       submesh_t *s = lookup_submesh(mesh, submesh);
+
+       if(s) {
+               meshlink_errno = MESHLINK_OK;
+               return s;
+       }
+
+       return submesh_add(mesh, submesh);
 }
 
 submesh_t *lookup_submesh(struct meshlink_handle *mesh, const char *submesh_name) {
+       assert(submesh_name);
+
        submesh_t *submesh = NULL;
 
        if(!mesh->submeshes) {
@@ -80,3 +128,11 @@ submesh_t *lookup_submesh(struct meshlink_handle *mesh, const char *submesh_name
 
        return submesh;
 }
+
+bool submesh_allows_node(const submesh_t *submesh, const node_t *node) {
+       if(!node->submesh || !submesh || submesh == node->submesh) {
+               return true;
+       } else {
+               return false;
+       }
+}