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

📄 user_agent.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 <unistd.h>#include "user_agent.h"#define USER_AGENT_LOG_LEVEL 20#define FIFO_PERMS (S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)using namespace freesecs;user_agent_t::user_agent_t(const char *in_ctl_fifo_name                            ,const char *out_ctl_fifo_name                            ,const char *in_data_fifo_name                            ,const char *out_data_fifo_name                            ,pcnx_t pcnx):_pcnx(pcnx){    char ar_name[64];    mode_t old_umask = umask(~FIFO_PERMS);    if(-1 == mkfifo(in_ctl_fifo_name, FIFO_PERMS))    {        umask(old_umask);        TRACE_ERROR("HSMSD: failed creating FIFO %s", in_ctl_fifo_name);        throw;    }    if(-1 == (_fd_ctl_in = open(in_ctl_fifo_name, O_RDWR)))    {        TRACE_ERROR("HSMSD: failed opening FIFO %s", in_ctl_fifo_name);        throw;    }    if(-1 == mkfifo(out_ctl_fifo_name, FIFO_PERMS))    {        umask(old_umask);        TRACE_ERROR("HSMSD: failed creating FIFO %s", out_ctl_fifo_name);        throw;    }    if(-1 == (_fd_ctl_out = open(out_ctl_fifo_name, O_RDWR)))    {        TRACE_ERROR("HSMSD: failed opening FIFO %s", out_ctl_fifo_name);        throw;    }    if(-1 == mkfifo(in_data_fifo_name, FIFO_PERMS))    {        umask(old_umask);        TRACE_ERROR("HSMSD: failed creating FIFO %s", in_data_fifo_name);        throw;    }    if(-1 == (_fd_data_in = open(in_data_fifo_name, O_RDWR)))    {        TRACE_ERROR("HSMSD: failed opening FIFO %s", in_data_fifo_name);        throw;    }    if(-1 == mkfifo(out_data_fifo_name, FIFO_PERMS))    {        umask(old_umask);        TRACE_ERROR("HSMSD: failed creating FIFO %s", out_data_fifo_name);        throw;    }    if(-1 == (_fd_data_out = open(out_data_fifo_name, O_RDWR)))    {        TRACE_ERROR("HSMSD: failed opening FIFO %s", out_data_fifo_name);        throw;    }    umask(old_umask);    _pcnx->rx_signal.add_handler(this, &user_agent_t::cnx_data_handler);    _pcnx->state_signal.add_handler(this, &user_agent_t::cnx_state_handler);    sprintf(ar_name, "%s client ctl", _pcnx->name());    _ar_ctl = new async_reception_t(_fd_ctl_in, ar_name);    _ar_ctl->data_recvd_signal.add_handler(this, &user_agent_t::user_ctl_handler);    _ar_ctl->recv_error_signal.add_handler(this, &user_agent_t::user_error_handler);    sprintf(ar_name, "%s client data", _pcnx->name());    _ar_data = new async_reception_t(_fd_data_in, ar_name);    _ar_data->data_recvd_signal.add_handler(this, &user_agent_t::user_data_handler);    _ar_data->recv_error_signal.add_handler(this, &user_agent_t::user_error_handler);    _ar_ctl->start_recv(&_client_ctl_req, sizeof(hsmsd_client_req_t));    _ar_data->start_recv(&_client_data_req, sizeof(hsmsd_client_req_t));}user_agent_t::~user_agent_t(){    _ar_ctl->stop_recv();    _ar_data->stop_recv();    close(_fd_ctl_in);    close(_fd_ctl_out);    close(_fd_data_in);    close(_fd_data_out);}int user_agent_t::user_ctl_handler(const size_t& num_bytes){    ua_req_handler_t::process_ctl(_client_ctl_req, num_bytes);    return 0;}int user_agent_t::user_data_handler(const size_t& num_bytes){    ua_req_handler_t::process_data(_client_data_req, num_bytes);    return 0;}int user_agent_t::user_error_handler(const int& err){    return 0;}int user_agent_t::cnx_data_handler(const hsms_socket_t::pdata_t& pdata){    int write_res;    hsmsd_server_rsp_t r;    data_msg<hsms_socket_t::data_t> hsms_msg;    hsms_socket_t::data_t hsms_msg_text;    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved signal from cnx %s", _pcnx->name());    if(false == hsms_msg.valid(*pdata))    {        TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved from cnx %s is not valid", _pcnx->name());        return -1;    }    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved from cnx %s is valid", _pcnx->name());    r.type = hsmsd_server_rsp_t::MSG_RECV;    r.u.msg_header.stream   = hsms_msg.stream(*pdata);    r.u.msg_header.function = hsms_msg.function(*pdata);    r.u.msg_header.wbit     = hsms_msg.wbit(*pdata);    r.u.msg_header.sysbytes = hsms_msg.transaction_id(*pdata);    r.u.msg_header.data_len = hsms_msg.text_len(*pdata);    write_res = ::write(_fd_data_out, &r, sizeof(r));        TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: s%df%d(0x%x), data len: %d, notified over client pipe: %d",                         r.u.msg_header.stream,                         r.u.msg_header.function,                         r.u.msg_header.sysbytes,                        r.u.msg_header.data_len,                        write_res);    if(0 < r.u.msg_header.data_len)    {        if(false == hsms_msg.get_text(*pdata, hsms_msg_text))        {            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,                        "HSMSD: failed to get "                        "text from msg recieved from cnx %s",                         _pcnx->name());            return -2;        }        write_res = ::write(_fd_data_out, &hsms_msg_text[0], hsms_msg_text.size());        TRACE_DEBUG(USER_AGENT_LOG_LEVEL,                        "HSMSD: s%df%d(0x%x), "                        "data len: %d, msg body "                        "written to client pipe: %d",                        r.u.msg_header.stream,                         r.u.msg_header.function,                         r.u.msg_header.sysbytes,                        r.u.msg_header.data_len,                        write_res);    }    return 0;}static hsmsd_server_rsp_t::cnx_state_t state_conv[e_hsms_not_connected_t5+1] =     {   hsmsd_server_rsp_t::CNX_NOT_CONNECTED,        hsmsd_server_rsp_t::CNX_NOT_SELECTED,        hsmsd_server_rsp_t::CNX_SELECTED,        hsmsd_server_rsp_t::CNX_NOT_CONNECTED    };intuser_agent_t::cnx_state_handler(const hsms_state_et& state){    hsmsd_server_rsp_t r;    r.type = hsmsd_server_rsp_t::CNX_STATE_EVT;    r.u.cnx_state = state_conv[(int)state];    ::write(_fd_ctl_out, &r, sizeof(r));    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: sent cnx state change to the client: %d", r.u.cnx_state);    return 0;}void user_agent_t::rcv_from_ctl(void *buf, size_t count){    _ar_ctl->start_recv(buf, count);}void user_agent_t::rcv_from_data(void *buf, size_t count){    _ar_data->start_recv(buf, count);}void user_agent_t::send_msg(hsms_cnx_t::pdata_t d){    hsmsd_server_rsp_t r;    r.type = hsmsd_server_rsp_t::MSG_SEND;    r.u.req_status = _pcnx->send(d);    ::write(_fd_data_out, &r, sizeof(r));}voiduser_agent_t::start_cnx(){    hsmsd_server_rsp_t r;    r.type = hsmsd_server_rsp_t::CNX_START;    r.u.req_status = _pcnx->start();    ::write(_fd_ctl_out, &r, sizeof(r));}void user_agent_t::stop_cnx(){    hsmsd_server_rsp_t r;    r.type = hsmsd_server_rsp_t::CNX_STOP;    r.u.req_status = _pcnx->stop();    ::write(_fd_ctl_out, &r, sizeof(r));}void user_agent_t::get_cnx_state(){    hsmsd_server_rsp_t r;    r.type = hsmsd_server_rsp_t::CNX_STATE_RSP;    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: cnx::get_state-->");    r.u.cnx_state = state_conv[(int)_pcnx->get_state()];    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: cnx::get_state<--");    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: write cnx state rsp-->");    ::write(_fd_ctl_out, &r, sizeof(r));    TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: write cnx state rsp<--");}ua_req_handler_t::ua_req_handler_t():_data_state(0){    _pmsg = new hsms_cnx_t::data_t;}/* * Client request handling SM * state 0: hsmsd_client_req_t struct reception * state 1: receiving data following hsmsd_client_req_t(MSG_SEND) * state 0 -> state 1: hsmsd_client_req_t(MSG_SEND) type recvd from client * state 1 -> state 0: all data following hsmsd_client_req_t(MSG_SEND) has been received */voidua_req_handler_t::process_data(hsmsd_client_req_t& req, size_t nb_rcvd){    data_msg<hsms_cnx_t::data_t> hsms_msg;    _nb_received += nb_rcvd;    if(hsmsd_client_req_t::MSG_SEND != req.type)    {        TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: unknown data send code: %d", req.type);        return;    }    switch(_data_state)    {        case 0:            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg send "                        "req from client (sysbytes: %d)",                         req.u.msg_header.sysbytes);            hsms_msg.compose(*_pmsg,                                req.u.msg_header.stream,                                req.u.msg_header.function,                                req.u.msg_header.wbit,                                req.u.msg_header.sysbytes,                                req.u.msg_header.data_len,                                NULL);            _msg_len = req.u.msg_header.data_len;            rcv_from_data((void*)&(*_pmsg)[HSMS_DATABYTES_OFFSET], req.u.msg_header.data_len);            _nb_received = 0;            _data_state = 1;        break;        case 1:            if(_nb_received == _msg_len)            {                _data_state = 0;                _nb_received = 0;                rcv_from_data((void*)&req, sizeof(req));                send_msg(_pmsg);            }        break;        default:            _data_state = 0;            _nb_received = 0;        break;    }}voidua_req_handler_t::process_ctl(hsmsd_client_req_t& req, size_t nb_rcvd){    switch(req.type)    {        case hsmsd_client_req_t::CNX_START:            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: start cnx req from client");            rcv_from_ctl(&req, sizeof(req));            start_cnx();        break;        case hsmsd_client_req_t::CNX_STOP:            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: stop cnx req from client");            rcv_from_ctl((void*)&req, sizeof(req));            stop_cnx();        break;        case hsmsd_client_req_t::CNX_STATE:            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: get cnx state req from client");            rcv_from_ctl((void*)&req, sizeof(req));            get_cnx_state();        break;        default:            TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: unknown ctl req code: %d", req.type);            break;    }}

⌨️ 快捷键说明

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