411 lines
10 KiB
C
411 lines
10 KiB
C
/*!
|
|
* 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 <strings.h>
|
|
#include <string.h>
|
|
|
|
#include <json.h>
|
|
#include <json_util.h>
|
|
|
|
#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;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
struct json_object *devices_manager_to_json_object(devices_manager_t *dm, const char *capability)
|
|
{
|
|
struct json_object *root_node;
|
|
// Sanity Checks
|
|
if (dm == NULL)
|
|
return NULL;
|
|
|
|
root_node = json_object_new_array();
|
|
|
|
if (capability == kOutletEntry)
|
|
{
|
|
}
|
|
else if (capability == kShutterEntry)
|
|
{
|
|
}
|
|
else if (capability == kSprinklerEntry)
|
|
{
|
|
}
|
|
|
|
return root_node;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
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, struct json_object *node)
|
|
{
|
|
int32_t id = -1;
|
|
struct json_object *value_node;
|
|
|
|
// id
|
|
if (json_object_object_get_ex(node, k_entry_id, &value_node))
|
|
{
|
|
id = json_object_get_int(value_node);
|
|
}
|
|
|
|
// 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;
|
|
}
|