/* * Authors: * Dmitriy A. Gearasimov <kahovski@gmail.com> * DeM Labs Inc. https://demlabs.net * DeM Labs Open source community https://github.com/demlabsinc * Copyright (c) 2017-2018 * All rights reserved. This file is part of DAP (Deus Applications Prototypes) the open source project DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. DAP 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 General Public License for more details. You should have received a copy of the GNU General Public License along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ #include <pthread.h> #include "uthash.h" #include "utlist.h" #include "dap_list.h" #include "dap_chain_net_srv.h" #define LOG_TAG "chain_net_srv" static size_t m_uid_count; static dap_chain_net_srv_uid_t * m_uid; typedef struct service_list { dap_chain_net_srv_uid_t uid; dap_chain_net_srv_t * srv; UT_hash_handle hh; } service_list_t; // list of active services static service_list_t *s_srv_list = NULL; // for separate access to s_srv_list static pthread_mutex_t s_srv_list_mutex = PTHREAD_MUTEX_INITIALIZER; /** * @brief dap_chain_net_srv_init * @return */ int dap_chain_net_srv_init(void) { m_uid = NULL; m_uid_count = 0; return 0; } /** * @brief dap_chain_net_srv_deinit */ void dap_chain_net_srv_deinit(void) { // TODO Stop all services dap_chain_net_srv_del_all(); } /** * @brief dap_chain_net_srv_add * @param a_srv */ void dap_chain_net_srv_add(dap_chain_net_srv_t * a_srv) { service_list_t *l_sdata = NULL; pthread_mutex_lock(&s_srv_list_mutex); HASH_FIND(hh, s_srv_list, &(a_srv->uid), sizeof(a_srv->uid), l_sdata); if(l_sdata == NULL) { l_sdata = DAP_NEW_Z(service_list_t); memcpy(&l_sdata->uid, &a_srv->uid, sizeof(dap_chain_net_srv_uid_t)); l_sdata->srv = DAP_NEW(dap_chain_net_srv_t); memcpy(&l_sdata->srv, a_srv, sizeof(dap_chain_net_srv_t)); ; HASH_ADD(hh, s_srv_list, uid, sizeof(a_srv->uid), l_sdata); } pthread_mutex_unlock(&s_srv_list_mutex); } /** * @brief dap_chain_net_srv_del * @param a_srv */ void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv) { service_list_t *l_sdata; pthread_mutex_lock(&s_srv_list_mutex); HASH_FIND(hh, s_srv_list, a_srv, sizeof(dap_chain_net_srv_uid_t), l_sdata); if(l_sdata) { DAP_DELETE(l_sdata); HASH_DEL(s_srv_list, l_sdata); } pthread_mutex_unlock(&s_srv_list_mutex); } /** * @brief dap_chain_net_srv_del_all * @param a_srv */ void dap_chain_net_srv_del_all(void) { service_list_t *l_sdata, *l_sdata_tmp; pthread_mutex_lock(&s_srv_list_mutex); HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) { DAP_DELETE(l_sdata); HASH_DEL(s_srv_list, l_sdata); } pthread_mutex_unlock(&s_srv_list_mutex); } /** * @brief dap_chain_net_srv_get * @param a_uid * @return */ dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t *a_uid) { service_list_t *l_sdata = NULL; pthread_mutex_lock(&s_srv_list_mutex); HASH_FIND(hh, s_srv_list, &a_uid, sizeof(dap_chain_net_srv_uid_t), l_sdata); pthread_mutex_unlock(&s_srv_list_mutex); return (l_sdata) ? l_sdata->srv : NULL; } /** * @brief dap_chain_net_srv_count * @return */ size_t dap_chain_net_srv_count(void) { size_t l_count = 0; service_list_t *l_sdata, *l_sdata_tmp; pthread_mutex_lock(&s_srv_list_mutex); HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) { l_count++; } pthread_mutex_unlock(&s_srv_list_mutex); return l_count; } /** * @brief dap_chain_net_srv_list * @return */ const dap_chain_net_srv_uid_t * dap_chain_net_srv_list(void) { static dap_chain_net_srv_uid_t *l_srv_uids = NULL; static size_t l_count_last = 0; size_t l_count_cur = 0; dap_list_t *l_list = NULL; service_list_t *l_sdata, *l_sdata_tmp; pthread_mutex_lock(&s_srv_list_mutex); // count the number of services and save them in list HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp) { l_list = dap_list_append(l_list, l_sdata); l_count_cur++; } // fill the output array if(l_count_cur > 0) { if(l_count_cur != l_count_last) { DAP_DELETE(l_srv_uids); l_srv_uids = DAP_NEW_SIZE(dap_chain_net_srv_uid_t, sizeof(dap_chain_net_srv_uid_t) * l_count_cur); } for(size_t i = 0; i < l_count_cur; i++) { service_list_t *l_sdata = l_list->data; memcpy(l_srv_uids + i, &l_sdata->uid, sizeof(dap_chain_net_srv_uid_t)); } } // save new number of services l_count_last = l_count_cur; pthread_mutex_unlock(&s_srv_list_mutex); dap_list_free(l_list); return l_srv_uids; }