00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string>
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <sys/param.h>
00024 #include "log.h"
00025 #include "hsms_msg.h"
00026 #include "hsms_socket.h"
00027 #include "tsqueue.h"
00028 #include "hsms_signums.h"
00029 #include "log.h"
00030
00031 #define HSMS_SOCK_LOG_LEVEL 9
00032
00033
00034 #define MAXRECV 1024
00035
00036 using namespace freesecs;
00037
00038 hsms_socket_t::hsms_socket_t(const char *name, const int port)
00039 :_remote_host(""), _port(port), _sock(-1)
00040 {
00041 _name = name;
00042 _name += " sock";
00043 _cnx_sm_name = _name;
00044 _cnx_sm_name += " cnx sm";
00045
00046 memset (&_addr, 0, sizeof (_addr));
00047
00048 if(0 != create_socket())
00049 {
00050 throw;
00051 }
00052 }
00053
00054 hsms_socket_t::hsms_socket_t(const char *name, const char *host, const int port)
00055 :_remote_host(host), _port(port), _sock(-1)
00056 {
00057 _name = name;
00058 _name += " sock";
00059 _cnx_sm_name = _name;
00060 _cnx_sm_name += " cnx sm";
00061
00062 memset (&_addr, 0, sizeof (_addr));
00063
00064 if(0 != create_socket())
00065 {
00066 throw;
00067 }
00068 }
00069
00070 int
00071 hsms_socket_t::create_socket()
00072 {
00073
00074 _sock = socket (AF_INET, SOCK_STREAM, 0);
00075 if (_sock <= 0)
00076 {
00077 TRACE_ERROR("%s: failed creating streaming socket", __func__);
00078 return errno;
00079 }
00080
00081 int on = 1;
00082
00083 if (setsockopt (_sock,
00084 SOL_SOCKET,
00085 SO_REUSEADDR,
00086 (const char *) &on,
00087 sizeof (on)) == -1)
00088 {
00089 TRACE_ERROR("%s: failed setting socket options", __func__);
00090 return errno;
00091 }
00092
00093 return 0;
00094 }
00095
00096 hsms_socket_t::~hsms_socket_t ()
00097 {
00098 disconnect();
00099 }
00100
00101 int
00102 hsms_socket_t::bind ()
00103 {
00104 if (_sock <= 0)
00105 {
00106 return EBADF;
00107 }
00108 _addr.sin_family = AF_INET;
00109 _addr.sin_addr.s_addr = htonl (INADDR_ANY);
00110 _addr.sin_port = htons (_port);
00111
00112 if(-1 == ::bind(_sock, (struct sockaddr*)&_addr, sizeof(_addr)))
00113 {
00114 return errno;
00115 }
00116
00117 return 0;
00118 }
00119
00120 int
00121 hsms_socket_t::listen ()
00122 {
00123 if (_sock <= 0)
00124 {
00125 return EBADF;
00126 }
00127
00128 if(-1 == ::listen (_sock, MAXCONNECTIONS))
00129 {
00130 return errno;
00131 }
00132
00133 return 0;
00134 }
00135
00136 int
00137 hsms_socket_t::accept ()
00138 {
00139 sock_cnx_ev_t ev;
00140 int new_sock = 0;
00141 int addr_length = sizeof (_addr);
00142
00143 new_sock =::accept (_sock, (sockaddr *) & _addr, (socklen_t *) & addr_length);
00144
00145 if (new_sock <= 0)
00146 {
00147 return errno;
00148 }
00149 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "hsms_socket_t::accept: cnx established");
00150
00151 ::shutdown(_sock, SHUT_RDWR);
00152 ::close (_sock);
00153 _sock = new_sock;
00154
00155 return 0;
00156 }
00157
00158 int freesecs::hsms_socket_t::connect_to()
00159 {
00160 if (_sock <= 0)
00161 {
00162 TRACE_ERROR("hsms_socket_t::remote_connect - socket is not valid");
00163 return EBADF;
00164 }
00165 _addr.sin_family = AF_INET;
00166 _addr.sin_port = htons (_port);
00167 int
00168 status = inet_pton (AF_INET, _remote_host.c_str (), &_addr.sin_addr);
00169
00170 if (status && errno == EAFNOSUPPORT)
00171 {
00172 TRACE_ERROR("hsms_socket_t::remote_connect - invalid address: %s", _remote_host.c_str());
00173 return errno;
00174 }
00175
00176 if(-1 == ::connect (_sock, (sockaddr *) & _addr, sizeof (_addr)))
00177 {
00178 TRACE_ERROR("hsms_socket_t::remote_connect - failed connecting to address: %s/%d",
00179 _remote_host.c_str(), _port);
00180 return errno;
00181 }
00182 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "hsms_socket_t::remote_connect to %s/%d OK!",
00183 _remote_host.c_str(), _port);
00184
00185 return 0;
00186 }
00187
00188 int
00189 hsms_socket_t::connect_tcp()
00190 {
00191 int r = 0;
00192
00193 if(0 == _sock)
00194 {
00195 if(0 != (r=create_socket()))
00196 {
00197 TRACE_ERROR("hsms_socket_t::connect: create socket failed: %s", strerror(r));
00198 return r;
00199 }
00200 }
00201
00202 if(_remote_host.length() == 0)
00203 {
00204 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "hsms_socket_t::connect: bind");
00205 if(0 != (r = bind()))
00206 {
00207 TRACE_ERROR("hsms_socket_t::connect: bind failed: %s", strerror(errno));
00208 return r;
00209 }
00210 if(0 != (r = listen()))
00211 {
00212 TRACE_ERROR("hsms_socket_t::connect: listen failed: %s", strerror(errno));
00213 return r;
00214 }
00215
00216 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL,"hsms_socket_t::connect: accept");
00217
00218 r = accept();
00219 if(0 != r)
00220 {
00221 TRACE_ERROR("hsms_socket_t::connect: accept failed: %s", strerror(errno));
00222 return r;
00223 }
00224 }
00225 else
00226 {
00227 r = connect_to();
00228 }
00229 return r;
00230 }
00231
00232 int
00233 hsms_socket_t::disconnect_tcp()
00234 {
00235 int r = 0;
00236
00237 if(::shutdown(_sock, SHUT_RDWR))
00238 {
00239 r = errno;
00240 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "hsms_socket_t::disconnect: shutdown returned %s", strerror(r));
00241 }
00242
00243 if(::close(_sock))
00244 {
00245 r = errno;
00246 TRACE_ERROR("hsms_socket_t::disconnect: close returned %s", strerror(r));
00247 }
00248
00249 _sock = 0;
00250
00251
00252 return 0;
00253 }
00254
00255 hsms_socket_t::cnx_state_et
00256 hsms_socket_t::get_cnx_state() const
00257 {
00258 return _cnx_state;
00259 }
00260
00261 int
00262 hsms_socket_t::connect()
00263 {
00264 sock_cnx_ev_t ev = {e_connect,};
00265 return process(ev);
00266 }
00267
00268 int
00269 hsms_socket_t::disconnect()
00270 {
00271 sock_cnx_ev_t ev = {e_disconnect,};
00272 return process(ev);
00273 }
00274
00275 int
00276 hsms_socket_t::send (pdata_t pdata)
00277 {
00278 sock_cnx_ev_t ev = {e_send, pdata};
00279 return process(ev);
00280 }
00281
00282 int
00283 hsms_socket_t::receive(pdata_t pdata)
00284 {
00285 sock_cnx_ev_t ev = {e_recv, pdata};
00286 return process(ev);
00287 }
00288
00289 int
00290 hsms_socket_t::send_tcp(pdata_t pd)
00291 {
00292 int r = 0;
00293 ssize_t sent, size = (*pd).size();
00294
00295 sent = ::send (_sock, (void*)pd->data(), size, MSG_NOSIGNAL);
00296
00297 if(sent != size)
00298 {
00299 r = errno;
00300 }
00301
00302 return r;
00303 }
00304
00305 int
00306 hsms_socket_t::process(sock_cnx_ev_t ev)
00307 {
00308 int r = 0;
00309 cnx_state_et state_old = _cnx_state;
00310
00311 TRACE_FSM_BEGIN(HSMS_SOCK_LOG_LEVEL, _cnx_sm_name.c_str(), _cnx_state, ev.type);
00312
00313 switch(_cnx_state)
00314 {
00315 case NOT_CONNECTED:
00316 if(e_connect == ev.type)
00317 {
00318 _cnx_state = CONNECTING;
00319 }
00320 else
00321 {
00322 goto sm_wrong_ev;
00323 }
00324 break;
00325 case CONNECTING:
00326 if(e_connected == ev.type)
00327 {
00328 _cnx_state = CONNECTED;
00329 }
00330 else if(e_connect_failed == ev.type)
00331 {
00332 r = z3(ev);
00333 _cnx_state = NOT_CONNECTED;
00334 }
00335 else if(e_disconnect == ev.type)
00336 {
00337 _cnx_state = NOT_CONNECTED;
00338 }
00339 else
00340 {
00341 goto sm_wrong_ev;
00342 }
00343 break;
00344 case CONNECTED:
00345 if(e_disconnect == ev.type)
00346 {
00347 _cnx_state = NOT_CONNECTED;
00348 }
00349 else if(e_send == ev.type)
00350 {
00351 r = z1(ev);
00352 }
00353 else if(e_recv == ev.type)
00354 {
00355 r = z2(ev);
00356 }
00357 else
00358 {
00359 goto sm_wrong_ev;
00360 }
00361 break;
00362 default:
00363 r = ENOTSUP;
00364 break;
00365 }
00366
00367 if(state_old == _cnx_state)
00368 {
00369 goto sm_end;
00370 }
00371
00372 TRACE_FSM_TRANS(HSMS_SOCK_LOG_LEVEL, _cnx_sm_name.c_str(), state_old, _cnx_state);
00373
00374 switch(_cnx_state)
00375 {
00376 case NOT_CONNECTED:
00377 r = z1_0(ev);
00378 break;
00379 case CONNECTING:
00380 r = z2_0(ev);
00381 break;
00382 case CONNECTED:
00383 r = z3_0(ev);
00384 break;
00385 default:
00386 r = ENOTSUP;
00387 break;
00388 }
00389 sm_end:
00390 TRACE_FSM_END(HSMS_SOCK_LOG_LEVEL, _cnx_sm_name.c_str(), _cnx_state, ev.type);
00391 return r;
00392 sm_wrong_ev:
00393
00394 TRACE_FSM_ERROR(HSMS_SOCK_LOG_LEVEL, _cnx_sm_name.c_str(),
00395 ", %s: event %d not handled in current state: %d",
00396 _name.c_str(), ev.type, _cnx_state);
00397 TRACE_FSM_END(HSMS_SOCK_LOG_LEVEL, _name.c_str(), _cnx_state, ev.type);
00398 return ENOTSUP;
00399 }
00400
00401 int
00402 hsms_socket_t::z1(sock_cnx_ev_t ev)
00403 {
00404 return send_tcp(ev.pdata);
00405 }
00406
00407 int
00408 hsms_socket_t::z2(sock_cnx_ev_t ev)
00409 {
00410 return recv_tcp(ev.pdata);
00411 }
00412
00413 int
00414 hsms_socket_t::z3(sock_cnx_ev_t)
00415 {
00416 cnx_failed_signal();
00417 return 0;
00418 }
00419
00420 int
00421 hsms_socket_t::z1_0(sock_cnx_ev_t ev)
00422 {
00423 int r = disconnect_tcp();
00424 cnx_state_signal(_cnx_state);
00425 return r;
00426 }
00427
00428 int
00429 hsms_socket_t::z2_0(sock_cnx_ev_t ev)
00430 {
00431 int r = 0;
00432 pthread_t tid;
00433 pthread_attr_t attr;
00434
00435
00436 cnx_state_signal(_cnx_state);
00437
00438 pthread_attr_init(&attr);
00439 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00440
00441 if(pthread_create(&tid, &attr, tcp_cnx_thread, (void*)this))
00442 {
00443 r = errno;
00444 }
00445
00446 pthread_attr_destroy(&attr);
00447
00448 return r;
00449 }
00450
00451 int
00452 hsms_socket_t::z3_0(sock_cnx_ev_t ev)
00453 {
00454 cnx_state_signal(_cnx_state);
00455 return 0;
00456 }
00457
00458 void *
00459 hsms_socket_t::tcp_cnx_thread(void *arg)
00460 {
00461 int r;
00462 sock_cnx_ev_t ev;
00463 hsms_socket_t *psock = (hsms_socket_t*)arg;
00464
00465 r = psock->connect_tcp();
00466 if(0 == r)
00467 {
00468 ev.type = e_connected;
00469 }
00470 else
00471 {
00472 ev.type = e_connect_failed;
00473 }
00474
00475 psock->process(ev);
00476
00477 pthread_exit(NULL);
00478 }
00479
00480
00481 hsms_socket_async_t::hsms_socket_async_t(const char *name, const int port)
00482 :hsms_socket_t(name, port)
00483 {
00484 }
00485
00486 hsms_socket_async_t::hsms_socket_async_t(const char *name, const char *host, int port)
00487 :hsms_socket_t(name, host, port),_ar(NULL)
00488 {
00489
00490 }
00491
00492 hsms_socket_async_t::~hsms_socket_async_t()
00493 {
00494 disconnect();
00495 }
00496
00497 int
00498 hsms_socket_async_t::disconnect_tcp()
00499 {
00500 process(e_i_deinit);
00501 return freesecs::hsms_socket_t::disconnect_tcp();
00502 }
00503
00504 int
00505 hsms_socket_async_t::recv_tcp(pdata_t pmessage)
00506 {
00507 _pmessage = pmessage;
00508 process(e_i_init);
00509 return EWOULDBLOCK;
00510 }
00511
00512 #if 0
00513 bool
00514 hsms_socket_async_t::x1()
00515 {
00516 bool valid = HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN == _bytes_read;
00517 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00518 return valid;
00519
00520 }
00521
00522 bool
00523 hsms_socket_async_t::x2()
00524 {
00525 int msg_len = ntohl(HSMS_MSG_LEN(&(*_pmessage)[0]));
00526 bool valid = msg_len >= HSMS_HDR_LEN;
00527 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": len %d, valid %d",
00528 msg_len,
00529 valid);
00530 return valid;
00531 }
00532
00533 bool
00534 hsms_socket_async_t::x3()
00535 {
00536
00537
00538
00539 bool valid = HSMS_HDR_LEN <= ntohl(HSMS_MSG_LEN(&(*_pmessage)[0]))
00540 && _pmessage->size() >= HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN
00541 && hsms_msg_base<data_t>::e_separate_req
00542 >= HSMS_MSG_STYPE(&(*_pmessage)[0]);
00543
00544 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00545 return valid;
00546 }
00547
00548 bool
00549 hsms_socket_async_t::x4()
00550 {
00551 hsms_msg_base<data_t> msg_base;
00552 bool valid = hsms_msg_base<data_t>::e_data == msg_base.type(*_pmessage);
00553 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00554 return valid;
00555 }
00556
00557 bool
00558 hsms_socket_async_t::x5()
00559 {
00560 bool valid = _rx_error > 0;
00561 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00562 return valid;
00563 }
00564
00565 bool
00566 hsms_socket_async_t::x6()
00567 {
00568 data_msg<data_t> msg;
00569 bool valid = msg.text_len(*_pmessage) <= _bytes_read
00570 - HSMS_LEN_BYTES_LEN - HSMS_HDR_LEN;
00571 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00572 return valid;
00573 }
00574
00575 int
00576 hsms_socket_async_t::z0()
00577 {
00578 int len = HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN;
00579
00580 if(!_pmessage.get())
00581 {
00582 _pmessage = new data_t;
00583 }
00584
00585 _pmessage->resize(len, 0);
00586
00587 if(NULL == _ar.get())
00588 {
00589 _ar = new async_reception_t(_sock, _name.c_str());
00590 _ar->data_partially_recvd_signal.add_handler(this, &freesecs::hsms_socket_async_t::data_rcvd_handler);
00591 _ar->data_recvd_signal.add_handler(this, &freesecs::hsms_socket_async_t::data_rcvd_handler);
00592 _ar->recv_error_signal.add_handler(this, &freesecs::hsms_socket_async_t::rcv_error_handler);
00593 }
00594 _ar->start_recv((void*)&(*_pmessage)[0], len);
00595
00596 return 0;
00597 }
00598
00599 int
00600 hsms_socket_async_t::z1()
00601 {
00602 data_msg<data_t> msg;
00603
00604 unsigned text_len = msg.text_len(*_pmessage);
00605 unsigned total_len = HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN + text_len;
00606
00607 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL,
00608 "%s::z1: text length %d,"
00609 " total length %d",
00610 _name.c_str(),
00611 text_len, total_len);
00612
00613 if(_bytes_read < total_len)
00614 {
00615 _pmessage->resize(total_len, 0);
00616 }
00617
00618 _ar->start_recv((void*)&(*_pmessage)[HSMS_DATABYTES_OFFSET], text_len);
00619
00620 return 0;
00621 }
00622
00623 int
00624 hsms_socket_async_t::z3()
00625 {
00626 state_signal(e_again);
00627 return 0;
00628 }
00629
00630 int
00631 hsms_socket_async_t::z4()
00632 {
00633 state_signal(e_again);
00634 return 0;
00635 }
00636
00637 int
00638 hsms_socket_async_t::z5()
00639 {
00640 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "%s::z5: disconnect...", _name.c_str());
00641
00642 _ar->stop_recv();
00643 _ar = NULL;
00644 return 0;
00645 }
00646
00647 int
00648 hsms_socket_async_t::z1_0()
00649 {
00650 _rx_error = 0;
00651 _bytes_read = 0;
00652 *_pmessage = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00653
00654 state_signal(_state);
00655 return 0;
00656 }
00657
00658 int
00659 hsms_socket_async_t::z2_0()
00660 {
00661 state_signal(_state);
00662 return 0;
00663 }
00664
00665 int
00666 hsms_socket_async_t::z3_0()
00667 {
00668 state_signal(_state);
00669 msg_signal(_pmessage);
00670 return 0;
00671 }
00672
00673 int
00674 hsms_socket_async_t::z4_0()
00675 {
00676 state_signal(_state);
00677 return 0;
00678 }
00679 #endif
00680
00695 void
00696 hsms_socket_async_t::process(internal_event_t e)
00697 {
00698 state_t state_old = _state;
00699
00700 TRACE_FSM_BEGIN(HSMS_SOCK_LOG_LEVEL, _name.c_str(), _state, e);
00701
00702 switch(_state)
00703 {
00704 case inactive:
00705 if(e_i_init == e)
00706 {
00707 _state = wtg_for_header;
00708 }
00709 break;
00710 case wtg_for_header:
00711 if(e_i_deinit == e)
00712 {
00713 _state = inactive;
00714 }
00715 else if(e_i_data_received == e)
00716 {
00717
00718
00719 if(x0())
00720 {
00721 if(x2())
00722 {
00723 z1();
00724 z1_0();
00725 }
00726 else
00727 {
00728 _state = wtg_for_data;
00729 }
00730 }
00731 else
00732 {
00733 z2();
00734 }
00735 }
00736 else if(e_i_recv_error == e)
00737 {
00738
00739
00740 z0();
00741 z3();
00742 }
00743 break;
00744 case wtg_for_data:
00745 if(e_i_deinit == e)
00746 {
00747 _state = inactive;
00748 }
00749 else if(e_i_data_received == e)
00750 {
00751
00752
00753 if(x1())
00754 {
00755
00756 z1();
00757 _state = wtg_for_header;
00758 }
00759 else
00760 {
00761 z2();
00762 }
00763 }
00764 else if(e_i_recv_error == e)
00765 {
00766
00767
00768 z3();
00769 _state = wtg_for_header;
00770 }
00771 default:
00772 break;
00773 }
00774
00775 if(state_old == _state)
00776 {
00777 goto sm_end;
00778 }
00779
00780 TRACE_FSM_TRANS(HSMS_SOCK_LOG_LEVEL, _name.c_str(), state_old, _state);
00781
00782 switch(_state)
00783 {
00784 case inactive:
00785 z0_0();
00786 break;
00787 case wtg_for_header:
00788 z1_0();
00789 break;
00790 case wtg_for_data:
00791 z2_0();
00792 default:
00793 break;
00794 }
00795
00796 sm_end:
00797 TRACE_FSM_END(HSMS_SOCK_LOG_LEVEL, _name.c_str(), _state, e);
00798 return;
00799 }
00800
00801 bool
00802 hsms_socket_async_t::x0()
00803 {
00804 bool valid = HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN == _bytes_read;
00805 valid &= HSMS_HDR_LEN <= ntohl(HSMS_MSG_LEN(&(*_pmessage)[0]))
00806 && _pmessage->size() >= HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN
00807 && hsms_msg_base<data_t>::e_separate_req
00808 >= HSMS_MSG_STYPE(&(*_pmessage)[0]);
00809 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00810 return valid;
00811 }
00812 bool
00813 hsms_socket_async_t::x1()
00814 {
00815 hsms_msg_base<data_t> msg_base;
00816
00817 bool valid = msg_base.valid(*_pmessage);
00818 TRACE_FSM_ACTION(HSMS_SOCK_LOG_LEVEL, _name.c_str(), __func__, ": %d", valid);
00819 return valid;
00820 }
00821 bool
00822 hsms_socket_async_t::x2()
00823 {
00824 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&(*_pmessage)[0]));
00825 }
00826 void
00827 hsms_socket_async_t::z0()
00828 {
00829 _rx_error = 0;
00830 _bytes_read = 0;
00831 *_pmessage = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00832 }
00833 void
00834 hsms_socket_async_t::z1()
00835 {
00836 msg_signal(_pmessage);
00837 }
00838 void
00839 hsms_socket_async_t::z2()
00840 {
00841 data_partially_recvd();
00842 }
00843 void
00844 hsms_socket_async_t::z3()
00845 {
00846 recv_error();
00847 }
00848 void
00849 hsms_socket_async_t::z0_0()
00850 {
00851 _ar->stop_recv();
00852 _ar = NULL;
00853 }
00854 void
00855 hsms_socket_async_t::z1_0()
00856 {
00857 _rx_error = 0;
00858 _bytes_read = 0;
00859 *_pmessage = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00860
00861 if(NULL == _ar.get())
00862 {
00863 _ar = new async_reception_t(_sock, _name.c_str());
00864 _ar->data_partially_recvd_signal.add_handler(this, &freesecs::hsms_socket_async_t::data_rcvd_handler);
00865 _ar->data_recvd_signal.add_handler(this, &freesecs::hsms_socket_async_t::data_rcvd_handler);
00866 _ar->recv_error_signal.add_handler(this, &freesecs::hsms_socket_async_t::rcv_error_handler);
00867 }
00868
00869 _ar->start_recv(&(*_pmessage)[0], _pmessage->size());
00870 }
00871 void
00872 hsms_socket_async_t::z2_0()
00873 {
00874 data_msg<data_t> msg;
00875
00876 unsigned text_len = msg.text_len(*_pmessage);
00877 unsigned total_len = HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN + text_len;
00878
00879 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL,
00880 "%s::z1: text length %d,"
00881 " total length %d",
00882 _name.c_str(),
00883 text_len, total_len);
00884
00885 if(_bytes_read < total_len)
00886 {
00887 _pmessage->resize(total_len, 0);
00888 }
00889
00890 _ar->start_recv((void*)&(*_pmessage)[HSMS_DATABYTES_OFFSET], text_len);
00891 }
00892
00893 #if 0
00894 void
00895 hsms_socket_async_t::process(internal_event_t e)
00896 {
00897 state_t state_old = _state;
00898
00899 TRACE_FSM_BEGIN(HSMS_SOCK_LOG_LEVEL, _name.c_str(), _state, e);
00900
00901 switch(_state)
00902 {
00903 case idle:
00904 if(e_i_init == e)
00905 {
00906 z0();
00907 _state = wtg_for_header;
00908 }
00909 break;
00910 case msg_received:
00911 case error:
00912 if(e_i_init == e)
00913 {
00914 z0();
00915 _state = wtg_for_header;
00916 }
00917 else if(e_i_cancelled == e)
00918 {
00919 z5();
00920 _state = idle;
00921 }
00922 break;
00923 case wtg_for_header:
00924 if(e_i_data_received == e)
00925 {
00926 if(x5())
00927 {
00928 _state = error;
00929 }
00930 else if(!x1())
00931 {
00932 z3();
00933 }
00934 else if(!(x2() && x3()))
00935 {
00936 _state = error;
00937 }
00938 else if(x4())
00939 {
00940 z1();
00941 _state = wtg_for_data;
00942 }
00943 else
00944 {
00945 _state = msg_received;
00946 }
00947 }
00948 else if(e_i_cancelled == e)
00949 {
00950 z5();
00951 _state = idle;
00952 }
00953 #ifdef GRACEFUL_RECEIVE
00954 if(error == _state)
00955 {
00956 z0();
00957 state_old = idle;
00958 _state= wtg_for_header;
00959 }
00960 #endif
00961 break;
00962 case wtg_for_data:
00963 if(e_i_data_received == e)
00964 {
00965 if(!x6())
00966 {
00967 z4();
00968 }
00969 else if(!x5())
00970 {
00971 _state = msg_received;
00972 }
00973 else
00974 {
00975 _state = error;
00976 }
00977
00978 }
00979 else if(e_i_cancelled == e)
00980 {
00981 z5();
00982 _state = idle;
00983 }
00984 default:
00985 break;
00986 }
00987
00988 if(state_old == _state)
00989 {
00990 goto sm_end;
00991 }
00992
00993 TRACE_FSM_TRANS(HSMS_SOCK_LOG_LEVEL, _name.c_str(), state_old, _state);
00994
00995 switch(_state)
00996 {
00997 case idle:
00998 break;
00999 case wtg_for_header:
01000 z1_0();
01001 break;
01002 case wtg_for_data:
01003 z2_0();
01004 break;
01005 case msg_received:
01006 z3_0();
01007 break;
01008 case error:
01009 z4_0();
01010 break;
01011 default:
01012 break;
01013 }
01014
01015 sm_end:
01016 TRACE_FSM_END(HSMS_SOCK_LOG_LEVEL, _name.c_str(), _state, e);
01017 return;
01018 }
01019 #endif
01020
01021 int
01022 hsms_socket_async_t::data_rcvd_handler(const size_t &num_bytes)
01023 {
01024 _bytes_read += num_bytes;
01025 process(e_i_data_received);
01026 return 0;
01027 }
01028
01029 int
01030 hsms_socket_async_t::rcv_error_handler(const int &err)
01031 {
01032 _rx_error = err;
01033 if(ECANCELED == err)
01034 {
01035 process(e_i_deinit);
01036 }
01037 else
01038 {
01039 _bytes_read = 0;
01040 process(e_i_data_received);
01041 }
01042 return 0;
01043 }
01044
01045
01046
01047
01048 #ifdef USE_TIMED_SOCK
01049 static char
01050 buf[MAXRECV];
01051 int
01052 hsms_socket_timed_t::_recv (data_t & data, size_t size,
01053 bool wait_all, bool flash_unwanted,
01054 int timeout) const
01055 {
01056 int retcode = 0;
01057
01058 if (MAXRECV < size)
01059 return -1;
01060 int flags = wait_all && size ? MSG_WAITALL : 0;
01061
01062 size_t actual_size = flash_unwanted ? MAXRECV : size;
01063 memset (buf, 0, MAXRECV);
01064 int status =::recv (_sock, buf, actual_size, flags);
01065
01066 if (status < 0)
01067
01068 {
01069 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "hsms_socket_timed_t::_recv: status: -1 errno: %d", errno);
01070 if (EWOULDBLOCK == errno)
01071
01072 {
01073 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "recv timeout in hsms_socket_timed_t::recv!!");
01074 retcode = -1;
01075 }
01076 retcode = status;
01077 }
01078
01079 else if (status == 0)
01080
01081 {
01082 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "cnx closed from other side!");
01083 retcode = -2;
01084 }
01085
01086 else if (size > 0)
01087
01088 {
01089 char *begin = buf;
01090 char *end = buf + status;
01091
01092 data.reserve (status);
01093 data.assign (begin, end);
01094 }
01095 return retcode;
01096 }
01097 int
01098 hsms_socket_timed_t::recv (data_t & d, int timeout_ms) const
01099 {
01100 if(timeout_ms)
01101 {
01102 _set_timer (_sock, timeout_ms);
01103 }
01104 return _recv (d, MAXRECV, false, false, 0);
01105 }
01106 int
01107 hsms_socket_timed_t::recvn (data_t & d, size_t size, int timeout_ms) const
01108 {
01109 if(timeout_ms)
01110 {
01111 _set_timer (_sock, timeout_ms);
01112 }
01113 return _recv (d, size, true, false, 0);
01114 }
01115
01116 void
01117 hsms_socket_timed_t::set_non_blocking (const bool b)
01118 {
01119 int opts;
01120
01121 opts = fcntl (_sock, F_GETFL);
01122 if (opts < 0)
01123
01124 {
01125 return;
01126 }
01127 if (b)
01128 opts = (opts | O_NONBLOCK);
01129
01130 else
01131 opts = (opts & ~O_NONBLOCK);
01132 fcntl (_sock, F_SETFL, opts);
01133 }
01134 void
01135 hsms_socket_timed_t::_set_timer (int sock_fd, int timeout_ms)
01136 {
01137 timeval tv;
01138
01139 if (sock_fd <= 0)
01140 {
01141 return;
01142 }
01143
01144 if (0 >= timeout_ms)
01145 {
01146 tv.tv_sec = 0;
01147 tv.tv_usec = 0;
01148 }
01149
01150 else
01151
01152 {
01153 tv.tv_sec = timeout_ms / 1000;
01154 tv.tv_usec = MAX (0, MAX (0, timeout_ms - 1000 * tv.tv_sec) * 1000);
01155 }
01156 ::setsockopt (sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof (tv));
01157 TRACE_DEBUG(HSMS_SOCK_LOG_LEVEL, "sock timer: sec=%d usec=%d", tv.tv_sec, tv.tv_usec);
01158 }
01159 #endif