diff --git a/CMakeLists.txt b/CMakeLists.txt index 472df84b202a3c3a85588b7a8f043a528a1a619f..a707cbfd9ae67103a7e20d0568f4828ec9d8bed1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(DAP_CHAIN_NET_SRV_SRCS dap_chain_net_srv_key.c dap_chain_net_srv_client.c dap_chain_net_srv_common.c + dap_chain_net_srv_stream_session.c ) set(DAP_CHAIN_NET_SRV_HEADERS @@ -15,6 +16,7 @@ set(DAP_CHAIN_NET_SRV_HEADERS dap_chain_net_srv_order.h dap_chain_net_srv_key.h dap_chain_net_srv_common.h + dap_chain_net_srv_stream_session.h ) diff --git a/dap_chain_net_srv.c b/dap_chain_net_srv.c index acc816210b288aa4a358c5fd6023620a1fba3353..1a690e3f2fabeda8148af854a95289fec83304fc 100755 --- a/dap_chain_net_srv.c +++ b/dap_chain_net_srv.c @@ -392,11 +392,14 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) /** * @brief dap_chain_net_srv_add * @param a_uid - * @param a_callback_new + * @param a_callback_request + * @param a_callback_response_success + * @param a_callback_response_error + * @return */ -dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_request) +dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_request, + dap_chain_net_srv_callback_data_t a_callback_response_success,dap_chain_net_srv_callback_data_t a_callback_response_error) { - int ret=0; service_list_t *l_sdata = NULL; dap_chain_net_srv_t * l_srv = NULL; dap_chain_net_srv_uid_t l_uid = {.uint64 = a_uid.uint64 }; // Copy to let then compiler to pass args via registers not stack @@ -406,6 +409,8 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_cha l_srv = DAP_NEW_Z(dap_chain_net_srv_t); l_srv->uid.uint64 = a_uid.uint64; l_srv->callback_requested = a_callback_request; + l_srv->callback_response_success = a_callback_response_success; + l_srv->callback_response_error = a_callback_response_error; l_sdata = DAP_NEW_Z(service_list_t); memcpy(&l_sdata->uid, &l_uid, sizeof(l_uid)); l_sdata->srv = DAP_NEW(dap_chain_net_srv_t); diff --git a/dap_chain_net_srv.h b/dap_chain_net_srv.h index 7cb033d59c1af9679c0740d8d736eaf33b6ce763..b11c48fe2384a781e6975adaf28f55c13ccc6122 100755 --- a/dap_chain_net_srv.h +++ b/dap_chain_net_srv.h @@ -31,7 +31,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic typedef struct dap_chain_net_srv dap_chain_net_srv_t; typedef void (*dap_chain_net_srv_callback_t)(dap_chain_net_srv_t *, dap_chain_net_srv_client_t *); -typedef int (*dap_chain_net_srv_callback_data_t)(dap_chain_net_srv_t *, dap_chain_net_srv_client_t *, const void *, size_t ); +typedef int (*dap_chain_net_srv_callback_data_t)(dap_chain_net_srv_t *, uint32_t, dap_chain_net_srv_client_t *, const void *, size_t ); typedef struct dap_chain_net_srv { @@ -49,7 +49,9 @@ typedef void (*dap_chain_net_srv_callback_new_t)(dap_chain_net_srv_t *, dap_conf int dap_chain_net_srv_init(dap_config_t * a_cfg); void dap_chain_net_srv_deinit(void); -dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_request); +dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_chain_net_srv_callback_data_t a_callback_requested, + dap_chain_net_srv_callback_data_t a_callback_response_success, + dap_chain_net_srv_callback_data_t a_callback_response_error); void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv); void dap_chain_net_srv_del_all(void); dap_chain_net_srv_t * dap_chain_net_srv_get(dap_chain_net_srv_uid_t a_uid); diff --git a/dap_chain_net_srv_common.h b/dap_chain_net_srv_common.h index d0e8548158fcec8fa845db9051a03719caba2bd8..08f29345efcc607298a5b1b0033c4ef28302f7cf 100755 --- a/dap_chain_net_srv_common.h +++ b/dap_chain_net_srv_common.h @@ -90,6 +90,58 @@ typedef struct dap_chain_net_srv_price } dap_chain_net_srv_price_t; +// Ch pkt types +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST 0x01 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST 0x10 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_RESPONSE 0x11 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_SUCCESS 0xf0 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR 0xff + +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNDEFINED 0x00000000 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND 0x00000100 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NOT_FOUND 0x00000200 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_NETWORK_NO_LEDGER 0x00000201 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_USAGE_CANT_ADD 0x00000300 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_FOUND 0x00000400 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NO_COND_OUT 0x00000401 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ENOUGH 0x00000402 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_NOT_ACCEPT_TOKEN 0x00000403 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SRV_UID 0x00000404 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_TX_COND_WRONG_SIZE 0x00000404 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND 0x00000500 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_NO_SIGN 0x00000501 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND 0x00000600 +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_WRONG_PKEY_HASH 0x00000502 + +#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNKNOWN 0xffffffff +// TYPE_REQUEST +typedef struct dap_stream_ch_chain_net_srv_pkt_request_hdr{ + dap_chain_net_id_t net_id;// Network id wheither to request + dap_chain_hash_fast_t tx_cond; // Conditioned transaction with paymemt for + dap_chain_net_srv_uid_t srv_uid; +} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_hdr_t; + +typedef struct dap_stream_ch_chain_net_srv_pkt_request{ + dap_stream_ch_chain_net_srv_pkt_request_hdr_t hdr; + uint8_t data[]; +} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_request_t; + +typedef struct dap_stream_ch_chain_net_srv_pkt_success_hdr{ + uint32_t usage_id; +} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_hdr_t; + +typedef struct dap_stream_ch_chain_net_srv_pkt_success{ + dap_stream_ch_chain_net_srv_pkt_success_hdr_t hdr; + uint8_t custom_data[]; +} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_success_t; + +// TYPE_RESPONSE_ERROR +typedef struct dap_stream_ch_chain_net_srv_pkt_error{ + uint32_t code; // error code +} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_error_t; + + + DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid ) { diff --git a/dap_chain_net_srv_stream_session.c b/dap_chain_net_srv_stream_session.c new file mode 100644 index 0000000000000000000000000000000000000000..60d4e57add52bc53070231f01276471d7e755ba2 --- /dev/null +++ b/dap_chain_net_srv_stream_session.c @@ -0,0 +1,115 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK 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. + +CellFrame SDK 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 CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "dap_common.h" +#include "rand/dap_rand.h" +#include "dap_chain_net_srv_stream_session.h" + +#define LOG_TAG "dap_stream_ch_chain_net_srv_session" + +/** + * @brief dap_chain_net_srv_stream_session_create + * @param a_session + * @return + */ +dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( dap_stream_session_t * a_session) +{ + if (!a_session){ + log_it (L_ERROR, "Session is NULL!"); + return NULL; + } + dap_chain_net_srv_stream_session_t * l_session_srv= DAP_NEW_Z(dap_chain_net_srv_stream_session_t); + a_session->_inheritor = l_session_srv; + log_it(L_NOTICE, "created service session"); + return l_session_srv; +} + +/** + * @brief dap_chain_net_srv_usage_add + * @param a_srv_session + * @param a_net + * @param a_srv + * @return + */ +dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream_session_t * a_srv_session, + dap_chain_net_t * a_net, dap_chain_net_srv_t * a_srv) +{ + if ( a_srv_session && a_net && a_srv ){ + dap_chain_net_srv_usage_t * l_ret = DAP_NEW_Z(dap_chain_net_srv_usage_t); + randombytes(&l_ret->id, sizeof(l_ret->id)); + l_ret->net = a_net; + l_ret->service = a_srv; + pthread_rwlock_init(&l_ret->rwlock,NULL); + pthread_mutex_lock(&a_srv_session->parent->mutex); + HASH_ADD_INT( a_srv_session->usages, id,l_ret ); + pthread_mutex_unlock(&a_srv_session->parent->mutex); + log_it( L_NOTICE, "Added service %s:0x%016llX usage ", l_ret->net->pub.name, a_srv->uid.uint64 ); + return l_ret; + }else{ + log_it( L_ERROR, "Some NULLs was in input"); + return NULL; + } +} + +/** + * @brief dap_chain_net_srv_usage_delete + * @param a_srv_session + * @param a_usage + * @return + */ +void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, + dap_chain_net_srv_usage_t* a_usage) +{ + if ( a_usage->receipt ) + DAP_DELETE( a_usage->receipt ); + if ( a_usage->clients ){ + for (dap_chain_net_srv_client_t * l_srv_client = a_usage->clients, * tmp = NULL; l_srv_client; ){ + tmp = l_srv_client; + l_srv_client = l_srv_client->next; + DAP_DELETE( tmp); + } + + + } + pthread_mutex_lock(&a_srv_session->parent->mutex); + HASH_DEL(a_srv_session->usages, a_usage); + pthread_mutex_unlock(&a_srv_session->parent->mutex); + DAP_DELETE( a_usage ); +} + +/** + * @brief dap_chain_net_srv_usage_find + * @param a_srv_session + * @param a_usage_id + * @return + */ +dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_find (dap_chain_net_srv_stream_session_t * a_srv_session, + uint32_t a_usage_id) +{ + dap_chain_net_srv_usage_t * l_ret = NULL; + pthread_mutex_lock(&a_srv_session->parent->mutex); + HASH_FIND_INT(a_srv_session->usages, &a_usage_id, l_ret); + pthread_mutex_unlock(&a_srv_session->parent->mutex); + return l_ret; +} diff --git a/dap_chain_net_srv_stream_session.h b/dap_chain_net_srv_stream_session.h new file mode 100644 index 0000000000000000000000000000000000000000..610c20b0110532da6ccdc9e755cda1cb8282f0d2 --- /dev/null +++ b/dap_chain_net_srv_stream_session.h @@ -0,0 +1,73 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK 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. + +CellFrame SDK 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 CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "pthread.h" +#include "uthash.h" +#include "dap_stream_session.h" +#include "dap_hash.h" +#include "dap_chain.h" +#include "dap_sign.h" +#include "dap_chain_datum_tx.h" +#include "dap_chain_datum_tx_receipt.h" +#include "dap_chain_net_srv.h" +#include "dap_chain_net_srv_order.h" +#include "dap_chain_net_srv_client.h" +#include "dap_chain_wallet.h" +typedef struct dap_chain_net_srv_usage{ + uint32_t id; // Usage id + pthread_rwlock_t rwlock; + time_t ts_created; // Created timpestamp + dap_chain_net_t * net; // Chain network where everything happens + dap_chain_wallet_t * wallet; + dap_chain_net_srv_t * service; // Service that used + dap_chain_datum_tx_receipt_t* receipt; + size_t receipt_size; + dap_chain_net_srv_client_t * clients; + dap_chain_datum_tx_t * tx_cond; + dap_chain_hash_fast_t tx_cond_hash; + char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; + bool is_active; + UT_hash_handle hh; // +} dap_chain_net_srv_usage_t; + +typedef struct dap_chain_net_srv_stream_session { + dap_stream_session_t * parent; + dap_chain_net_srv_usage_t * usages; + dap_chain_net_srv_usage_t * usage_active; + uint64_t bytes_sent; + uint64_t bytes_received; + time_t ts_activated; + dap_sign_t* user_sign; // User's signature for auth if reconnect +} dap_chain_net_srv_stream_session_t; + +#define DAP_CHAIN_NET_SRV_STREAM_SESSION(a) ((dap_chain_net_srv_stream_session_t *) (a)->_inheritor ) + +dap_chain_net_srv_stream_session_t * dap_chain_net_srv_stream_session_create( dap_stream_session_t * a_session); +dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_add (dap_chain_net_srv_stream_session_t * a_srv_session, + dap_chain_net_t * a_net, dap_chain_net_srv_t * a_srv); +void dap_chain_net_srv_usage_delete (dap_chain_net_srv_stream_session_t * a_srv_session, + dap_chain_net_srv_usage_t* a_usage); +dap_chain_net_srv_usage_t* dap_chain_net_srv_usage_find (dap_chain_net_srv_stream_session_t * a_srv_session, + uint32_t a_usage_id);