📄 user_agent.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 + -