/*! * devices_manager.c * * Copyright (c) 2015-2020, NADAL Jean-Baptiste. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * @Author: NADAL Jean-Baptiste * @Date: 23/12/2019 * */ // This is an independent project of an individual developer. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com /*-------------------------------- INCLUDES ---------------------------------*/ #include #include #include #include #include "macro.h" #include "domo.h" #include "outlet_dio.h" #include "shutter.h" #include "sprinkler.h" #include "devices_manager_internal.h" #include "devices_manager.h" /*----------------------------- LOCAL FUNCTIONS ----------------------------*/ /*----------------------------- PUBLIC FUNCTIONS ----------------------------*/ /*--------------------------------------------------------------------------*/ devices_manager_t *devices_manager_new(void) { devices_manager_t *devices_manager = NEW_OBJECT(devices_manager_t); if (devices_manager == NULL) { return NULL; } bzero((void *)devices_manager, sizeof(devices_manager_t)); // Initialize instance. devices_manager->outlets = qlist(0); devices_manager->shutters = qlist(0); devices_manager->sprinklers = qlist(0); return devices_manager; } /*--------------------------------------------------------------------------*/ void devices_manager_free(devices_manager_t *devices_manager) { qlist_obj_t obj; int i; memset((void *)&obj, 0, sizeof(obj)); if (devices_manager == NULL) return; if (devices_manager->outlets) { i = 0; while (qlist_getnext(devices_manager->outlets, &obj, true)) { outlet_dio_free(obj.data); i++; } qlist_free(devices_manager->outlets); } if (devices_manager->shutters) { i = 0; while (qlist_getnext(devices_manager->shutters, &obj, true)) { shutter_free(obj.data); i++; } qlist_free(devices_manager->shutters); } if (devices_manager->sprinklers) { i = 0; while (qlist_getnext(devices_manager->sprinklers, &obj, true)) { sprinkler_free(obj.data); i++; } qlist_free(devices_manager->sprinklers); } if (devices_manager->file_path != NULL) { free(devices_manager->file_path); } if (devices_manager->capabilities_path != NULL) { free(devices_manager->capabilities_path); } free(devices_manager); } /*--------------------------------------------------------------------------*/ int devices_manager_load(devices_manager_t *dm, char *config_path) { struct json_object *the_root_node, *the_value_node; DEBUG("Devices load...\n"); if (config_path == NULL) { fprintf(stderr, "Couldn't found the device config file.\n"); return -1; } dm->file_path = config_path; the_root_node = json_object_from_file(dm->file_path); if (the_root_node == NULL) { fprintf(stderr, "Failed to parse the Devices File (%s).\n", dm->file_path); return -1; } if (json_object_object_get_ex(the_root_node, kOutletEntry, &the_value_node)) { load_outlets(dm, the_value_node); } if (json_object_object_get_ex(the_root_node, kShutterEntry, &the_value_node)) { load_shutters(dm, the_value_node); } if (json_object_object_get_ex(the_root_node, kSprinklerEntry, &the_value_node)) { load_sprinklers(dm, the_value_node); } /* Clean the json object. */ json_object_put(the_root_node); return 0; } /*--------------------------------------------------------------------------*/ int devices_manager_save(devices_manager_t *dm) { int result; struct json_object *root_node; DEBUG("Devices save...\n"); root_node = json_object_new_object(); // Outlets json_object_object_add(root_node, kOutletEntry, save_outlets(dm)); // Shutters json_object_object_add(root_node, kShutterEntry, save_shutters(dm)); // Sprinklers json_object_object_add(root_node, kSprinklerEntry, save_sprinklers(dm)); result = json_object_to_file_ext(dm->file_path, root_node, JSON_C_TO_STRING_PRETTY); /* Clean the json object. */ json_object_put(root_node); return result; } /*--------------------------------------------------------------------------*/ int devices_manager_set_capabilities_path(devices_manager_t *dm, char *path) { dm->capabilities_path = strdup(path); } /*--------------------------------------------------------------------------*/ char *devices_manager_get(devices_manager_t *dm, const char *capability) { json_object *output_node; char *output = NULL; // Sanity Checks if (dm == NULL) return NULL; if (capability == kOutletEntry) { output_node = devices_manager_outlets_to_json_object(dm); } else if (capability == kShutterEntry) { output_node = devices_manager_shutters_to_json_object(dm); } else if (capability == kSprinklerEntry) { output_node = devices_manager_sprinklers_to_json_object(dm); } if (output_node != NULL) { output = strdup(json_object_to_json_string(output_node)); json_object_put(output_node); } return output; } /*--------------------------------------------------------------------------*/ char *devices_manager_get_by_id(devices_manager_t *dm, const char *capability, uint32_t id) { char *output = NULL; // Sanity Checks if (dm == NULL) return NULL; if (capability == kOutletEntry) { outlet_dio_t *outlet_dio; outlet_dio = get_outlet_by_id(dm, id); if (outlet_dio != NULL) { json_object *output_node = outlet_dio_to_json_object(outlet_dio); if (output_node != NULL) { output = strdup(json_object_to_json_string(output_node)); json_object_put(output_node); } } } else if (capability == kShutterEntry) { shutter_t *shutter; shutter = get_shutter_by_id(dm, id); if (shutter != NULL) { json_object *output_node = shutter_to_json_object(shutter); if (output_node != NULL) { output = strdup(json_object_to_json_string(output_node)); json_object_put(output_node); } } } else if (capability == kSprinklerEntry) { sprinkler_t *sprinkler; sprinkler = get_sprinkler_by_id(dm, id); if (sprinkler != NULL) { json_object *output_node = sprinkler_to_json_object(sprinkler); if (output_node != NULL) { output = strdup(json_object_to_json_string(output_node)); json_object_put(output_node); } } } return output; } /*--------------------------------------------------------------------------*/ int devices_manager_create(devices_manager_t *dm, const char *capability, struct json_object *node) { // Sanity checks if ((dm == NULL) || (node == NULL)) return -1; if (capability == kOutletEntry) { return create_outlet(dm, node); } else if (capability == kShutterEntry) { return create_shutter(dm, node); } else if (capability == kSprinklerEntry) { return create_sprinkler(dm, node); } return -1; } /*--------------------------------------------------------------------------*/ int devices_manager_update(devices_manager_t *dm, const char *capability, struct json_object *node) { int32_t id = -1; struct json_object *value_node; if ((dm == NULL) || (node == NULL)) return -1; // id if (json_object_object_get_ex(node, k_entry_id, &value_node)) { id = json_object_get_int(value_node); } // state if (!json_object_object_get_ex(node, k_entry_state, &value_node)) { return -1; } // Sanity checks. if (id == -1) return -1; if (capability == kOutletEntry) { return update_outlet(dm, id, node); } else if (capability == kShutterEntry) { return update_shutter(dm, id, node); } else if (capability == kSprinklerEntry) { return update_sprinkler(dm, id, node); } return -1; } /*--------------------------------------------------------------------------*/ int devices_manager_delete(devices_manager_t *dm, const char *capability, uint32_t id) { // Sanity checks. if (id == -1) return -1; if (capability == kOutletEntry) { return remove_outlet(dm, id); } else if (capability == kShutterEntry) { return remove_shutter(dm, id); } else if (capability == kSprinklerEntry) { return remove_sprinkler(dm, id); } return -1; }