00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022 #include <fcntl.h>
00023 #include <unistd.h>
00024 #include "user_agent.h"
00025
00026 #define USER_AGENT_LOG_LEVEL 20
00027
00028 #define FIFO_PERMS (S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
00029
00030 using namespace freesecs;
00031
00032 user_agent_t::user_agent_t(const char *in_ctl_fifo_name
00033 ,const char *out_ctl_fifo_name
00034 ,const char *in_data_fifo_name
00035 ,const char *out_data_fifo_name
00036 ,pcnx_t pcnx)
00037 :_pcnx(pcnx)
00038 {
00039 char ar_name[64];
00040 mode_t old_umask = umask(~FIFO_PERMS);
00041
00042 if(-1 == mkfifo(in_ctl_fifo_name, FIFO_PERMS))
00043 {
00044 umask(old_umask);
00045 TRACE_ERROR("HSMSD: failed creating FIFO %s", in_ctl_fifo_name);
00046 throw;
00047 }
00048
00049 if(-1 == (_fd_ctl_in = open(in_ctl_fifo_name, O_RDWR)))
00050 {
00051 TRACE_ERROR("HSMSD: failed opening FIFO %s", in_ctl_fifo_name);
00052 throw;
00053 }
00054
00055 if(-1 == mkfifo(out_ctl_fifo_name, FIFO_PERMS))
00056 {
00057 umask(old_umask);
00058 TRACE_ERROR("HSMSD: failed creating FIFO %s", out_ctl_fifo_name);
00059 throw;
00060 }
00061
00062 if(-1 == (_fd_ctl_out = open(out_ctl_fifo_name, O_RDWR)))
00063 {
00064 TRACE_ERROR("HSMSD: failed opening FIFO %s", out_ctl_fifo_name);
00065 throw;
00066 }
00067 if(-1 == mkfifo(in_data_fifo_name, FIFO_PERMS))
00068 {
00069 umask(old_umask);
00070 TRACE_ERROR("HSMSD: failed creating FIFO %s", in_data_fifo_name);
00071 throw;
00072 }
00073
00074 if(-1 == (_fd_data_in = open(in_data_fifo_name, O_RDWR)))
00075 {
00076 TRACE_ERROR("HSMSD: failed opening FIFO %s", in_data_fifo_name);
00077 throw;
00078 }
00079 if(-1 == mkfifo(out_data_fifo_name, FIFO_PERMS))
00080 {
00081 umask(old_umask);
00082 TRACE_ERROR("HSMSD: failed creating FIFO %s", out_data_fifo_name);
00083 throw;
00084 }
00085
00086 if(-1 == (_fd_data_out = open(out_data_fifo_name, O_RDWR)))
00087 {
00088 TRACE_ERROR("HSMSD: failed opening FIFO %s", out_data_fifo_name);
00089 throw;
00090 }
00091
00092 umask(old_umask);
00093
00094 _pcnx->rx_signal.add_handler(this, &user_agent_t::cnx_data_handler);
00095 _pcnx->state_signal.add_handler(this, &user_agent_t::cnx_state_handler);
00096
00097 sprintf(ar_name, "%s client ctl", _pcnx->name());
00098
00099 _ar_ctl = new async_reception_t(_fd_ctl_in, ar_name);
00100 _ar_ctl->data_recvd_signal.add_handler(this, &user_agent_t::user_ctl_handler);
00101 _ar_ctl->recv_error_signal.add_handler(this, &user_agent_t::user_error_handler);
00102
00103 sprintf(ar_name, "%s client data", _pcnx->name());
00104 _ar_data = new async_reception_t(_fd_data_in, ar_name);
00105 _ar_data->data_recvd_signal.add_handler(this, &user_agent_t::user_data_handler);
00106 _ar_data->recv_error_signal.add_handler(this, &user_agent_t::user_error_handler);
00107
00108 _ar_ctl->start_recv(&_client_ctl_req, sizeof(hsmsd_client_req_t));
00109 _ar_data->start_recv(&_client_data_req, sizeof(hsmsd_client_req_t));
00110 }
00111
00112 user_agent_t::~user_agent_t()
00113 {
00114 _ar_ctl->stop_recv();
00115 _ar_data->stop_recv();
00116 close(_fd_ctl_in);
00117 close(_fd_ctl_out);
00118 close(_fd_data_in);
00119 close(_fd_data_out);
00120 }
00121
00122 int
00123 user_agent_t::user_ctl_handler(const size_t& num_bytes)
00124 {
00125 ua_req_handler_t::process_ctl(_client_ctl_req, num_bytes);
00126
00127 return 0;
00128 }
00129
00130 int
00131 user_agent_t::user_data_handler(const size_t& num_bytes)
00132 {
00133 ua_req_handler_t::process_data(_client_data_req, num_bytes);
00134
00135 return 0;
00136 }
00137
00138 int
00139 user_agent_t::user_error_handler(const int& err)
00140 {
00141 return 0;
00142 }
00143
00144 int
00145 user_agent_t::cnx_data_handler(const hsms_socket_t::pdata_t& pdata)
00146 {
00147 int write_res;
00148 hsmsd_server_rsp_t r;
00149 data_msg<hsms_socket_t::data_t> hsms_msg;
00150 hsms_socket_t::data_t hsms_msg_text;
00151
00152 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved signal from cnx %s", _pcnx->name());
00153
00154 if(false == hsms_msg.valid(*pdata))
00155 {
00156 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved from cnx %s is not valid", _pcnx->name());
00157 return -1;
00158 }
00159 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg recieved from cnx %s is valid", _pcnx->name());
00160
00161 r.type = hsmsd_server_rsp_t::MSG_RECV;
00162
00163 r.u.msg_header.stream = hsms_msg.stream(*pdata);
00164 r.u.msg_header.function = hsms_msg.function(*pdata);
00165 r.u.msg_header.wbit = hsms_msg.wbit(*pdata);
00166 r.u.msg_header.sysbytes = hsms_msg.transaction_id(*pdata);
00167 r.u.msg_header.data_len = hsms_msg.text_len(*pdata);
00168
00169 write_res = ::write(_fd_data_out, &r, sizeof(r));
00170
00171 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: s%df%d(0x%x), data len: %d, notified over client pipe: %d",
00172 r.u.msg_header.stream,
00173 r.u.msg_header.function,
00174 r.u.msg_header.sysbytes,
00175 r.u.msg_header.data_len,
00176 write_res);
00177
00178 if(0 < r.u.msg_header.data_len)
00179 {
00180 if(false == hsms_msg.get_text(*pdata, hsms_msg_text))
00181 {
00182 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,
00183 "HSMSD: failed to get "
00184 "text from msg recieved from cnx %s",
00185 _pcnx->name());
00186
00187 return -2;
00188 }
00189
00190 write_res = ::write(_fd_data_out, &hsms_msg_text[0], hsms_msg_text.size());
00191 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,
00192 "HSMSD: s%df%d(0x%x), "
00193 "data len: %d, msg body "
00194 "written to client pipe: %d",
00195 r.u.msg_header.stream,
00196 r.u.msg_header.function,
00197 r.u.msg_header.sysbytes,
00198 r.u.msg_header.data_len,
00199 write_res);
00200 }
00201 return 0;
00202 }
00203
00204 static hsmsd_server_rsp_t::cnx_state_t state_conv[e_hsms_not_connected_t5+1] =
00205 { hsmsd_server_rsp_t::CNX_NOT_CONNECTED,
00206 hsmsd_server_rsp_t::CNX_NOT_SELECTED,
00207 hsmsd_server_rsp_t::CNX_SELECTED,
00208 hsmsd_server_rsp_t::CNX_NOT_CONNECTED
00209 };
00210
00211 int
00212 user_agent_t::cnx_state_handler(const hsms_state_et& state)
00213 {
00214 hsmsd_server_rsp_t r;
00215
00216 r.type = hsmsd_server_rsp_t::CNX_STATE_EVT;
00217 r.u.cnx_state = state_conv[(int)state];
00218 ::write(_fd_ctl_out, &r, sizeof(r));
00219 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: sent cnx state change to the client: %d", r.u.cnx_state);
00220
00221 return 0;
00222 }
00223
00224 void
00225 user_agent_t::rcv_from_ctl(void *buf, size_t count)
00226 {
00227 _ar_ctl->start_recv(buf, count);
00228 }
00229
00230 void
00231 user_agent_t::rcv_from_data(void *buf, size_t count)
00232 {
00233 _ar_data->start_recv(buf, count);
00234 }
00235
00236 void
00237 user_agent_t::send_msg(hsms_cnx_t::pdata_t d)
00238 {
00239 hsmsd_server_rsp_t r;
00240
00241 r.type = hsmsd_server_rsp_t::MSG_SEND;
00242 r.u.req_status = _pcnx->send(d);
00243 ::write(_fd_data_out, &r, sizeof(r));
00244 }
00245 void
00246 user_agent_t::start_cnx()
00247 {
00248 hsmsd_server_rsp_t r;
00249
00250 r.type = hsmsd_server_rsp_t::CNX_START;
00251 r.u.req_status = _pcnx->start();
00252
00253 ::write(_fd_ctl_out, &r, sizeof(r));
00254 }
00255 void
00256 user_agent_t::stop_cnx()
00257 {
00258 hsmsd_server_rsp_t r;
00259
00260 r.type = hsmsd_server_rsp_t::CNX_STOP;
00261 r.u.req_status = _pcnx->stop();
00262 ::write(_fd_ctl_out, &r, sizeof(r));
00263 }
00264 void
00265 user_agent_t::get_cnx_state()
00266 {
00267 hsmsd_server_rsp_t r;
00268
00269 r.type = hsmsd_server_rsp_t::CNX_STATE_RSP;
00270 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: cnx::get_state-->");
00271 r.u.cnx_state = state_conv[(int)_pcnx->get_state()];
00272 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: cnx::get_state<--");
00273 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: write cnx state rsp-->");
00274 ::write(_fd_ctl_out, &r, sizeof(r));
00275 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: write cnx state rsp<--");
00276 }
00277
00278 ua_req_handler_t::ua_req_handler_t()
00279 :_data_state(0)
00280 {
00281 _pmsg = new hsms_cnx_t::data_t;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 void
00291 ua_req_handler_t::process_data(hsmsd_client_req_t& req, size_t nb_rcvd)
00292 {
00293 data_msg<hsms_cnx_t::data_t> hsms_msg;
00294
00295 _nb_received += nb_rcvd;
00296
00297 if(hsmsd_client_req_t::MSG_SEND != req.type)
00298 {
00299 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: unknown data send code: %d", req.type);
00300 return;
00301 }
00302
00303 switch(_data_state)
00304 {
00305 case 0:
00306 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: msg send "
00307 "req from client (sysbytes: %d)",
00308 req.u.msg_header.sysbytes);
00309
00310 hsms_msg.compose(*_pmsg,
00311 req.u.msg_header.stream,
00312 req.u.msg_header.function,
00313 req.u.msg_header.wbit,
00314 req.u.msg_header.sysbytes,
00315 req.u.msg_header.data_len,
00316 NULL);
00317 _msg_len = req.u.msg_header.data_len;
00318 rcv_from_data((void*)&(*_pmsg)[HSMS_DATABYTES_OFFSET], req.u.msg_header.data_len);
00319 _nb_received = 0;
00320 _data_state = 1;
00321 break;
00322 case 1:
00323 if(_nb_received == _msg_len)
00324 {
00325 _data_state = 0;
00326 _nb_received = 0;
00327 rcv_from_data((void*)&req, sizeof(req));
00328 send_msg(_pmsg);
00329 }
00330 break;
00331 default:
00332 _data_state = 0;
00333 _nb_received = 0;
00334 break;
00335 }
00336 }
00337
00338
00339 void
00340 ua_req_handler_t::process_ctl(hsmsd_client_req_t& req, size_t nb_rcvd)
00341 {
00342 switch(req.type)
00343 {
00344 case hsmsd_client_req_t::CNX_START:
00345 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: start cnx req from client");
00346 rcv_from_ctl(&req, sizeof(req));
00347 start_cnx();
00348 break;
00349 case hsmsd_client_req_t::CNX_STOP:
00350 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: stop cnx req from client");
00351 rcv_from_ctl((void*)&req, sizeof(req));
00352 stop_cnx();
00353 break;
00354 case hsmsd_client_req_t::CNX_STATE:
00355 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: get cnx state req from client");
00356 rcv_from_ctl((void*)&req, sizeof(req));
00357 get_cnx_state();
00358 break;
00359 default:
00360 TRACE_DEBUG(USER_AGENT_LOG_LEVEL,"HSMSD: unknown ctl req code: %d", req.type);
00361 break;
00362 }
00363 }