mirror of
https://github.com/emqx/neuron.git
synced 2026-10-16 20:30:39 +08:00
201 lines
5.3 KiB
C
201 lines
5.3 KiB
C
/**
|
|
* NEURON IIoT System for Industry 4.0
|
|
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
|
*
|
|
* This program 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 3 of the License, or (at your option) any later version.
|
|
*
|
|
* This program 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 program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
#ifndef NEURON_PLUGIN_DATALAYERS_H
|
|
#define NEURON_PLUGIN_DATALAYERS_H
|
|
|
|
#include <stdbool.h>
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "neuron.h"
|
|
|
|
#include "datalayers/flight_sql_client.h"
|
|
#include "datalayers_config.h"
|
|
|
|
typedef struct {
|
|
char driver[NEU_NODE_NAME_LEN];
|
|
char group[NEU_GROUP_NAME_LEN];
|
|
} route_key_t;
|
|
|
|
typedef struct {
|
|
route_key_t key;
|
|
|
|
UT_hash_handle hh;
|
|
} route_entry_t;
|
|
|
|
#define MAX_QUEUE_SIZE 1000
|
|
|
|
typedef struct db_write_task_s {
|
|
UT_array * int_tags;
|
|
UT_array * float_tags;
|
|
UT_array * bool_tags;
|
|
UT_array * string_tags;
|
|
struct db_write_task_s *next;
|
|
bool freed;
|
|
} db_write_task_t;
|
|
|
|
typedef struct {
|
|
db_write_task_t *head;
|
|
db_write_task_t *tail;
|
|
int size;
|
|
int max_size;
|
|
} task_queue_t;
|
|
|
|
struct neu_plugin {
|
|
neu_plugin_common_t common;
|
|
datalayers_config_t config;
|
|
route_entry_t * route_tbl;
|
|
neu_datalayers_client *client;
|
|
|
|
task_queue_t task_queue;
|
|
pthread_t consumer_thread;
|
|
|
|
pthread_mutex_t queue_mutex;
|
|
pthread_cond_t queue_not_empty;
|
|
|
|
pthread_rwlock_t plugin_mutex;
|
|
bool consumer_thread_stop_flag;
|
|
|
|
uint32_t config_seq;
|
|
|
|
int (*parse_config)(neu_plugin_t *plugin, const char *setting,
|
|
datalayers_config_t *config);
|
|
};
|
|
|
|
static inline void route_entry_free(route_entry_t *e)
|
|
{
|
|
free(e);
|
|
}
|
|
|
|
static inline void route_tbl_free(route_entry_t *tbl)
|
|
{
|
|
route_entry_t *e = NULL, *tmp = NULL;
|
|
HASH_ITER(hh, tbl, e, tmp)
|
|
{
|
|
HASH_DEL(tbl, e);
|
|
route_entry_free(e);
|
|
}
|
|
}
|
|
|
|
static inline route_entry_t *
|
|
route_tbl_get(route_entry_t **tbl, const char *driver, const char *group)
|
|
{
|
|
route_entry_t *find = NULL;
|
|
route_key_t key = { 0 };
|
|
|
|
strncpy(key.driver, driver, sizeof(key.driver));
|
|
strncpy(key.group, group, sizeof(key.group));
|
|
|
|
HASH_FIND(hh, *tbl, &key, sizeof(key), find);
|
|
return find;
|
|
}
|
|
|
|
// NOTE: we take ownership of `topic`
|
|
static inline int route_tbl_add_new(route_entry_t **tbl, const char *driver,
|
|
const char *group)
|
|
{
|
|
route_entry_t *find = NULL;
|
|
|
|
find = route_tbl_get(tbl, driver, group);
|
|
if (find) {
|
|
return NEU_ERR_GROUP_ALREADY_SUBSCRIBED;
|
|
}
|
|
|
|
find = calloc(1, sizeof(*find));
|
|
if (NULL == find) {
|
|
return NEU_ERR_EINTERNAL;
|
|
}
|
|
|
|
strncpy(find->key.driver, driver, sizeof(find->key.driver));
|
|
strncpy(find->key.group, group, sizeof(find->key.group));
|
|
HASH_ADD(hh, *tbl, key, sizeof(find->key), find);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int route_tbl_update(route_entry_t **tbl, const char *driver,
|
|
const char *group)
|
|
{
|
|
route_entry_t *find = NULL;
|
|
|
|
find = route_tbl_get(tbl, driver, group);
|
|
if (NULL == find) {
|
|
return NEU_ERR_GROUP_NOT_SUBSCRIBE;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline void route_tbl_update_driver(route_entry_t **tbl,
|
|
const char * driver,
|
|
const char * new_name)
|
|
{
|
|
route_entry_t *e = NULL, *tmp = NULL;
|
|
HASH_ITER(hh, *tbl, e, tmp)
|
|
{
|
|
if (0 == strcmp(e->key.driver, driver)) {
|
|
HASH_DEL(*tbl, e);
|
|
strncpy(e->key.driver, new_name, sizeof(e->key.driver));
|
|
HASH_ADD(hh, *tbl, key, sizeof(e->key), e);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void route_tbl_update_group(route_entry_t **tbl,
|
|
const char *driver, const char *group,
|
|
const char *new_name)
|
|
{
|
|
route_entry_t *e = route_tbl_get(tbl, driver, group);
|
|
if (e) {
|
|
HASH_DEL(*tbl, e);
|
|
strncpy(e->key.group, new_name, sizeof(e->key.group));
|
|
HASH_ADD(hh, *tbl, key, sizeof(e->key), e);
|
|
}
|
|
}
|
|
|
|
static inline void route_tbl_del_driver(route_entry_t **tbl, const char *driver)
|
|
{
|
|
route_entry_t *e = NULL, *tmp = NULL;
|
|
HASH_ITER(hh, *tbl, e, tmp)
|
|
{
|
|
if (0 == strcmp(e->key.driver, driver)) {
|
|
HASH_DEL(*tbl, e);
|
|
route_entry_free(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void route_tbl_del(route_entry_t **tbl, const char *driver,
|
|
const char *group)
|
|
{
|
|
route_entry_t *find = NULL;
|
|
find = route_tbl_get(tbl, driver, group);
|
|
if (find) {
|
|
HASH_DEL(*tbl, find);
|
|
route_entry_free(find);
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif |