⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hsmsd_cnx_proxy.cpp

📁 与secs相关的hsms协议
💻 CPP
字号:
/*    *   (c) Copyright 2008 Philipp Skadorov (philipp_s@users.sourceforge.net) * *   This file is part of FREESECS. * *   FREESECS 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. * *   FREESECS 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 FREESECS, see COPYING. *   If not, see <http://www.gnu.org/licenses/>. */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "tsqueue.h"#include "log.h"#include "hsmsd_interface.h"#include "hsmsd_cnx_proxy.h"#define CNX_PROXY_LOG_LEVEL 1000using namespace freesecs;template<typename handler_t>int set_handler(handler_t &old_h, handler_t &new_h){    int r = 0;    if(old_h != NULL && new_h != NULL)    {        r = EPERM;    }    else if(old_h == new_h)    {        r = EALREADY;    }    else    {        old_h = new_h;    }    return r;}hsmsd_proxy_t::pump_events_to_client_t hsmsd_proxy_t::client_event_pump;hsmsd_proxy_t::hsmsd_proxy_t(const char *cnx_name):_cnx_name(cnx_name),_fd_ctl_in(0),_fd_ctl_out(0),_fd_data_in(0),_fd_data_out(0),_rstate(0),_msg_h(NULL),_cnx_state_h(NULL),_cnx_error_h(NULL){    int reg_fd, rsp_fd;    ssize_t req_sz, rsp_sz;    hsmsd_register_req_t register_req;    hsmsd_register_rsp_t register_rsp;    if(-1 == (reg_fd = ::open(HSMSD_REGISTER_FIFO_IN, O_RDWR)))    {        throw;    }    if(-1 == (rsp_fd = ::open(HSMSD_REGISTER_FIFO_OUT, O_RDWR)))    {        throw;    }        strncpy(register_req.cnx_name, cnx_name, HSMS_NAME_MAX_LEN);    register_req.cli_pid = getpid();    req_sz = sizeof(register_req);    if(req_sz != write(reg_fd, &register_req, req_sz))    {        throw;    }    rsp_sz = sizeof(register_rsp);    if(rsp_sz != read(rsp_fd, &register_rsp, rsp_sz))    {        throw;    }    if(hsmsd_register_rsp_t::REG_OK != register_rsp.rsp_code)    {        TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                     "HSMSCLI: register rsp: %d\n",                     register_rsp.rsp_code);        throw;    }        close(reg_fd);    close(rsp_fd);    TRACE_DEBUG(CNX_PROXY_LOG_LEVEL, "HSMSCLI: cnx %s : user pipes: %s, %s, %s, %s\n",                                   cnx_name,                                   register_rsp.pipe_name_ctl_req,                                   register_rsp.pipe_name_ctl_rsp,                                  register_rsp.pipe_name_data_req,                                  register_rsp.pipe_name_data_rsp);        if(-1 == (_fd_ctl_out = open(register_rsp.pipe_name_ctl_req, O_RDWR)))    {        throw;    }    if(-1 == (_fd_ctl_in = open(register_rsp.pipe_name_ctl_rsp, O_RDWR)))    {        throw;    }    if(-1 == (_fd_data_out = open(register_rsp.pipe_name_data_req, O_RDWR)))    {        throw;    }    if(-1 == (_fd_data_in = open(register_rsp.pipe_name_data_rsp, O_RDWR)))    {        throw;    }    for(int i=0; i < hsmsd_server_rsp_t::MAX_RSP_TYPE; ++i)    {        if(0 != sem_init(&_rsp_sem_pool[i], 0, 0))        {            throw;        }    }    std::string pipe_name = _cnx_name;    pipe_name += " ctrl";    _ctl_ar = new async_reception_t(_fd_ctl_in, pipe_name.c_str());    pipe_name = _cnx_name;    pipe_name += " data";    _data_ar = new async_reception_t(_fd_data_in, pipe_name.c_str());    _ctl_ar->data_recvd_signal.add_handler(this, &hsmsd_proxy_t::ctrl_rcvd_handler);    _ctl_ar->recv_error_signal.add_handler(this, &hsmsd_proxy_t::rcv_error_handler);    _data_ar->data_recvd_signal.add_handler(this, &hsmsd_proxy_t::data_rcvd_handler);    _data_ar->recv_error_signal.add_handler(this, &hsmsd_proxy_t::rcv_error_handler);    _ctl_ar->start_recv(&_srv_ctl_msg, sizeof(_srv_ctl_msg));    _data_ar->start_recv(&_srv_data_msg, sizeof(_srv_data_msg));}hsmsd_proxy_t::~hsmsd_proxy_t(){    _ctl_ar->stop_recv();    _data_ar->stop_recv();    close(_fd_ctl_in);    close(_fd_ctl_out);    close(_fd_data_in);    close(_fd_data_out);        for(size_t i=0; i < sizeof(_rsp_sem_pool); ++i)    {        sem_destroy(&_rsp_sem_pool[i]);    }}int hsmsd_proxy_t::set_msg_handler(hsmsd_msg_handler_t new_h){    return set_handler(_msg_h, new_h);}int hsmsd_proxy_t::set_cnx_state_handler(hsmsd_cnx_state_handler_t new_h){    return set_handler(_cnx_state_h, new_h);}int hsmsd_proxy_t::set_cnx_error_handler(hsmsd_cnx_error_handler_t new_h){    return set_handler(_cnx_error_h, new_h);}int hsmsd_proxy_t::start(){    int r = 0;    size_t len;    hsmsd_client_req_t req;        req.type = hsmsd_client_req_t::CNX_START;        len = write(_fd_ctl_out, &req, sizeof(req));        if(sizeof(req) == len)    {    TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                 "HSMSCLI: cnx %s : sent cnx start, "                "waiting for reply...\n",                 _cnx_name.c_str());        sem_wait(&_rsp_sem_pool[hsmsd_server_rsp_t::CNX_START]);        r = _srv_msg_pool[hsmsd_server_rsp_t::CNX_START].u.req_status;        TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                     "HSMSCLI: cnx %s : sent "                    "cnx start reply: %d\n",                     _cnx_name.c_str(), r);    }    else    {        r = errno;    }    return r;}int hsmsd_proxy_t::stop(){    int r = 0;    size_t len;    hsmsd_client_req_t req;        req.type = hsmsd_client_req_t::CNX_STOP;       len = write(_fd_ctl_out, &req, sizeof(req));        if(sizeof(req) == len)    {        sem_wait(&_rsp_sem_pool[hsmsd_server_rsp_t::CNX_STOP]);        r = _srv_msg_pool[hsmsd_server_rsp_t::CNX_STOP].u.req_status;    }    else    {        r = errno;    }    return r;}int hsmsd_proxy_t::get_state(hsmsd_cnx_state_t* state){    int r = 0;    size_t len;    hsmsd_client_req_t req;        req.type = hsmsd_client_req_t::CNX_STATE;        len = write(_fd_ctl_out, &req, sizeof(req));        if(sizeof(req) == len)    {        sem_wait(&_rsp_sem_pool[hsmsd_server_rsp_t::CNX_STATE_RSP]);        *state = (hsmsd_cnx_state_t)_srv_msg_pool[hsmsd_server_rsp_t::CNX_STATE_RSP].u.cnx_state;    }    else    {        r = errno;    }    return r;}int hsmsd_proxy_t::send_msg(hsmsd_msg_t* msg){    int r = 0;    ssize_t len;    hsmsd_client_req_t *req;    len = sizeof(hsmsd_client_req_t) + msg->data_len;    char *pmem = (char*)malloc(len);    memset(pmem, 0, sizeof(len));    if(msg->data_len)    {        memcpy(pmem + sizeof(hsmsd_client_req_t), msg->data, msg->data_len);    }    req = (hsmsd_client_req_t*)pmem;    req->type = hsmsd_client_req_t::MSG_SEND;    req->u.msg_header.stream     = msg->stream;    req->u.msg_header.function   = msg->function;    req->u.msg_header.wbit       = msg->wbit;    req->u.msg_header.sysbytes   = msg->sysbytes;    req->u.msg_header.data_len   = msg->data_len;    if(len != (r = write(_fd_data_out, pmem, len)))    {        r = errno;    }    else    {        sem_wait(&_rsp_sem_pool[hsmsd_server_rsp_t::MSG_SEND]);        r = _srv_msg_pool[hsmsd_server_rsp_t::MSG_SEND].u.req_status;    }    free(pmem);        return r;}int hsmsd_proxy_t::ctrl_rcvd_handler(const size_t &size){    size_t len = sizeof(_srv_ctl_msg);    if(size != len && _cnx_error_h)    {        //_cnx_error_h(-3);        client_event_pump << new error_event_t(_cnx_error_h, -3);    }    _srv_msg_pool[_srv_ctl_msg.type] = _srv_ctl_msg;    sem_post(&_rsp_sem_pool[_srv_ctl_msg.type]);    /*fire rsp type-specific handlers!*/    if(hsmsd_server_rsp_t::CNX_STATE_EVT == _srv_ctl_msg.type && _cnx_state_h)    {        //_cnx_state_h((hsmsd_cnx_state_t)_srv_ctl_msg.u.cnx_state);        client_event_pump << new state_event_t(_cnx_state_h, (hsmsd_cnx_state_t)_srv_ctl_msg.u.cnx_state);    }    else if(hsmsd_server_rsp_t::CNX_ERROR_EVT == _srv_ctl_msg.type && _cnx_error_h)    {        //_cnx_error_h(_srv_ctl_msg.u.cnx_error);        client_event_pump << new error_event_t(_cnx_error_h, _srv_ctl_msg.u.cnx_error);    }   _ctl_ar->start_recv(&_srv_ctl_msg, len);    return 0;}int hsmsd_proxy_t::data_rcvd_handler(const size_t &size){    hsmsd_msg_t *pmsg;    void *pbuf = &_srv_data_msg;    size_t len = sizeof(_srv_data_msg);    TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                 "HSMSCLI: server data response: "                "type=%d, req status=%d, "                "error=%d, cnx state=%d",                 _srv_data_msg.type,                 _srv_data_msg.u.req_status,                 _srv_data_msg.u.cnx_error,                 _srv_data_msg.u.cnx_state);    switch(_rstate)    {        case 0:            TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                        "HSMSCLI: receiving data: status=%d, "\                        "msg size=%d, expected size=%d",                         _rstate,                         size,                         len);            if(size == len && hsmsd_server_rsp_t::MSG_RECV == _srv_data_msg.type)            {                    //_msg_data.clear();                    _msg_data.resize(_srv_data_msg.u.msg_header.data_len, 0);                    _rstate = 1;                    pbuf = &_msg_data[0];                    len = _srv_data_msg.u.msg_header.data_len;            }            else if(size == len && hsmsd_server_rsp_t::MSG_SEND == _srv_data_msg.type)            {                _srv_msg_pool[_srv_data_msg.type] = _srv_data_msg;                sem_post(&_rsp_sem_pool[_srv_data_msg.type]);                _rstate = 0;            }            else if(_cnx_error_h)            {                //_cnx_error_h(-3);                client_event_pump << new error_event_t(_cnx_error_h, -3);            }        break;        case 1:            TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                        "HSMSCLI: receiving status=%d, "                        "msg size=%d, expected size=%d/%d",                         _rstate, size, _msg_data.size(),                        _srv_data_msg.u.msg_header.data_len);            if(size == _msg_data.size()                && size == _srv_data_msg.u.msg_header.data_len)            {                if(_msg_h)                {                    pmsg = (hsmsd_msg_t*)malloc(sizeof(hsmsd_msg_t) + size - 1);                    pmsg->stream    = _srv_data_msg.u.msg_header.stream;                    pmsg->function  = _srv_data_msg.u.msg_header.function;                    pmsg->wbit      = _srv_data_msg.u.msg_header.wbit;                    pmsg->sysbytes  = _srv_data_msg.u.msg_header.sysbytes;                    pmsg->data_len  = size;                    memcpy(&pmsg->data[0], &_msg_data[0], size);                                TRACE_DEBUG(CNX_PROXY_LOG_LEVEL,                                "HSMSCLI: s%df%d(0x%x) received from server"                                , pmsg->stream, pmsg->function                                , pmsg->sysbytes);                    client_event_pump << new msg_event_t(_msg_h, pmsg);                    //_msg_h(pmsg);                }                _srv_msg_pool[_srv_data_msg.type] = _srv_data_msg;                sem_post(&_rsp_sem_pool[_srv_data_msg.type]);            }            else            {                if(_cnx_error_h)                {                    client_event_pump << new error_event_t(_cnx_error_h, EBADMSG);                }            }            _rstate = 0;        break;    }    _data_ar->start_recv(pbuf, len);    return 0;}int hsmsd_proxy_t::rcv_error_handler(const int &err){    if(_cnx_error_h)    {        //_cnx_error_h(-5);        client_event_pump << new error_event_t(_cnx_error_h, EIO);    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -