Main Page   Class Hierarchy   Compound List   File List   Compound Members  

C_Socket.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 
00020 #include "C_Socket.hpp"
00021 #include "Utils.hpp"
00022 
00023 #include "iostream_t.hpp"
00024 
00025 #include <cerrno>     // for errno
00026 #include <cstring>    // for strerror
00027 #include <unistd.h>   // for close()
00028 #include <fcntl.h>
00029 
00030 //#define BUFLEN       1024
00031 //#define DECODEBUFLEN 2048
00032 //#define DECODEBUFLEN 4096
00033 
00034 #define SOCKET_ERROR(l,m) iostream_error << m << iostream_endl << iostream_flush
00035 #ifdef DEBUG_MODE
00036 #define SOCKET_DEBUG(l,m) iostream_error << m << iostream_endl << iostream_flush
00037 #else
00038 #define SOCKET_DEBUG(l,m)
00039 #endif
00040 
00041 int C_Socket::get_prototype() {
00042   int L_ret ;
00043 
00044   switch (m_type) {
00045   case E_SOCKET_TCP_MODE:
00046     L_ret = SOCK_STREAM ;
00047     break ;
00048   case E_SOCKET_UDP_MODE:
00049     L_ret = SOCK_DGRAM ;
00050     break ;
00051   default:
00052     L_ret = -1 ;
00053     break ;
00054   }
00055   return L_ret ;
00056 }
00057 
00058 int C_SocketWithData::_call_write(unsigned char* P_data,
00059                                   size_t P_size) {
00060   return (call_send(m_socket_id, P_data, P_size, 0));
00061 }
00062 
00063 int C_SocketWithData::_write(unsigned char* P_data,
00064                              size_t         P_size) {
00065   return (call_sendto(m_socket_id, P_data, P_size, 
00066                       0,
00067                       (struct sockaddr*)(void*)m_remote_sockaddr_ptr, 
00068                       (tool_socklen_t)*m_len_remote_sockaddr_ptr)) ;
00069 }
00070 
00071 size_t C_SocketListen::send_buffer(unsigned char     *P_data, 
00072                                    size_t             P_size) {
00073   return (0);
00074 }
00075 
00076 size_t C_SocketWithData::send_buffer(unsigned char     *P_data, 
00077                                      size_t             P_size){
00078   //                                     T_SockAddrStorage *P_remote_sockaddr,
00079   //                                     tool_socklen_t    *P_len_remote_sockaddr) {
00080   size_t L_size = 0 ;
00081   int    L_rc       ;
00082 
00083   SOCKET_DEBUG(0, "C_Socket::send_buffer(" 
00084             << m_socket_id << "," << P_data << "," << P_size << ")");
00085   
00086   SOCKET_DEBUG(0, "C_TransIP::send_buffer() id OK");
00087   
00088   if (m_type == E_SOCKET_TCP_MODE) {
00089     L_rc = _call_write(P_data, P_size) ;
00090   } else {
00091     L_rc = _write(P_data, P_size) ;
00092   }
00093 
00094   if (L_rc < 0) {
00095     SOCKET_ERROR(0, 
00096                  "send failed [" << L_rc << "] [" << strerror(errno) << "]");
00097     switch (errno) {
00098     case EAGAIN:
00099       SOCKET_ERROR(0, "Flow control not implemented");
00100       break ;
00101     case ECONNRESET:
00102       break ;
00103     default:
00104       SOCKET_ERROR(0, "process error [" << errno << "] not implemented");
00105       break ;
00106     }
00107   } else {
00108     L_size = P_size ;
00109     if(L_size != (size_t)L_rc){
00110        SOCKET_ERROR(0, "Sent message is incomplete");
00111     }
00112 
00113   }
00114     
00115   SOCKET_DEBUG(0, "C_TransIP::send_buffer() return " << L_size);
00116   return (L_size);
00117 
00118 }
00119 
00120 C_Socket::C_Socket(C_Socket &P_Socket) {
00121   m_socket_id = P_Socket.m_socket_id   ; 
00122   m_channel_id = P_Socket.m_channel_id     ;
00123   m_type = P_Socket.m_type        ;
00124   m_src_port = P_Socket.m_src_port    ;
00125   m_state = P_Socket.m_state       ;
00126   m_buffer_size = P_Socket.m_buffer_size ;
00127   m_protocol = P_Socket.m_protocol ;
00128 }
00129 
00130 C_Socket::C_Socket(int P_channel_id) {
00131    SOCKET_DEBUG(1, "C_Socket::C_Socket (" 
00132                 << P_channel_id 
00133                 << ") id="
00134                 << m_socket_id);
00135    m_socket_id = -1 ;
00136    m_channel_id = P_channel_id ;
00137    m_state = E_SOCKET_STATE_NOT_READY ;
00138 }
00139 
00140 C_Socket::C_Socket(T_SocketType P_type, 
00141                    int          P_port, 
00142                    int          P_channel_id) {
00143   
00144   SOCKET_DEBUG(1, "C_Socket::C_Socket (" 
00145                << P_port << "," << P_channel_id << ") id=" << m_socket_id);
00146 
00147   m_socket_id = -1 ;
00148   m_type = P_type ;
00149   m_src_port = P_port ;
00150 
00151   m_channel_id = P_channel_id ;
00152   m_state = E_SOCKET_STATE_NOT_READY ;
00153 }
00154 
00155 C_Socket::C_Socket(T_SocketType P_type, 
00156                    int          P_channel_id) {
00157   
00158   SOCKET_DEBUG(1, "C_Socket::C_Socket (" 
00159                << P_channel_id << ") id=" << m_socket_id);
00160   m_socket_id = -1 ;
00161   m_type = P_type ;
00162   m_channel_id = P_channel_id ;
00163   m_state = E_SOCKET_STATE_NOT_READY ;
00164 }
00165 
00166 C_pDataDecode C_Socket::get_decode() {
00167   return (NULL);
00168 }
00169 C_ProtocolBinaryFrame* C_Socket::get_protocol() {
00170   return (m_protocol);
00171 }
00172 T_pRcvMsgCtxtList C_Socket::get_list() {
00173   return (NULL);
00174 }
00175 
00176 
00177 void C_Socket::set_channel_id(int P_channel_id) {
00178   SOCKET_DEBUG(1, "C_Socket::set_channel_id(" << P_channel_id << ") id=" 
00179                << m_socket_id);
00180   m_channel_id = P_channel_id ;
00181 }
00182 
00183 int C_Socket::_open(int                    P_socket_domain, 
00184                     size_t                 P_buffer_size,
00185                     C_ProtocolBinaryFrame *P_protocol) {
00186   
00187   int L_socket_domain ; /* socket domain */
00188 
00189   SOCKET_DEBUG(1, "C_Socket::_open ()");
00190 
00191   m_buffer_size = P_buffer_size ;
00192   L_socket_domain = P_socket_domain ; 
00193 
00194   /* allocate a free socket                 */
00195   /* Internet address family, Stream socket */
00196   m_socket_id = call_socket(L_socket_domain, get_prototype(), 0);
00197   
00198   SOCKET_DEBUG(1, "m_socket_id [" << m_socket_id << "]");
00199 
00200   if (m_socket_id < 0) {
00201     perror("socket: allocation failed");
00202   }
00203 
00204   m_protocol = P_protocol ;
00205 
00206   set_properties();
00207   
00208   return (0) ;
00209 }
00210 
00211 C_Socket::~C_Socket() {
00212   SOCKET_DEBUG(1, "C_Socket::~C_Socket ()");
00213 }
00214 
00215 int C_Socket::get_id () {
00216   SOCKET_DEBUG(1, "C_Socket::get_id ()");
00217   return (m_socket_id);
00218 }
00219 
00220 int C_Socket::get_channel_id () {
00221   SOCKET_DEBUG(1, "C_Socket::get_id ()");
00222   return (m_channel_id);
00223 }
00224 
00225 
00226 void C_Socket::_close () {
00227   SOCKET_DEBUG(1, "C_Socket::_close ()");
00228   call_shutdown(m_socket_id, SHUT_RDWR);
00229   if (call_close(m_socket_id) != 0) {
00230     SOCKET_ERROR(0, 
00231                  "close socket ["
00232                  << m_socket_id
00233                  << "] failed ["
00234                  << errno
00235                  << "] ["
00236                  << strerror(errno)
00237                  << "]");
00238   }
00239 }
00240 
00241 
00242 void C_Socket::set_fd_set(fd_set *P_rSet, fd_set *P_wSet) {
00243   SOCKET_DEBUG(1, "C_Socket::set_fd_set () id=" << m_socket_id);
00244   switch (m_state) {
00245   case E_SOCKET_STATE_READY:
00246     FD_SET(m_socket_id, P_rSet);
00247     break ;
00248   case E_SOCKET_STATE_INPROGESS:
00249     FD_SET(m_socket_id, P_wSet);
00250     FD_SET(m_socket_id, P_rSet);
00251     break ;
00252   case E_SOCKET_STATE_NOT_READY:
00253     break ;
00254   }
00255 }
00256 
00257 void C_Socket::set_properties() {
00258 
00259   int           L_sock_opt ;
00260   unsigned int  L_max_buf_size ;
00261   struct linger L_linger ;
00262   int           L_flags ;
00263 
00264   if (m_type == E_SOCKET_TCP_MODE) {
00265     L_sock_opt = 1 ;
00266     // fast reuse of the socket
00267     if (call_setsockopt(m_socket_id, 
00268                        SOL_SOCKET, SO_REUSEADDR, (void *)&L_sock_opt,
00269                    sizeof (L_sock_opt)) == -1) {
00270       SOCKET_ERROR(1, "setsockopt(SO_REUSEADDR) failed");
00271     }
00272     // no data grouped
00273     L_sock_opt = 1 ;
00274     if (call_setsockopt (m_socket_id, 
00275                         IPPROTO_TCP, TCP_NODELAY, (void *)&L_sock_opt,
00276                     sizeof (L_sock_opt)) == -1) {
00277       SOCKET_ERROR(1, "setsockopt(TCP_NODELAY) failed");
00278     }
00279     // max wait time after a close
00280     L_linger.l_onoff = 1;
00281     L_linger.l_linger = 0;
00282     if (call_setsockopt (m_socket_id, SOL_SOCKET, SO_LINGER,
00283                     &L_linger, sizeof (L_linger)) < 0) {
00284       SOCKET_ERROR(1, "Unable to set SO_LINGER option");
00285     }
00286   }
00287 
00288   // size of recv buf
00289   L_max_buf_size = m_buffer_size ;
00290   if(call_setsockopt(m_socket_id, SOL_SOCKET, SO_SNDBUF,
00291                     &L_max_buf_size, sizeof(L_max_buf_size))) {
00292     SOCKET_ERROR(1,"Unable to set socket sndbuf");
00293   }
00294 
00295   // size of send buff
00296   L_max_buf_size = m_buffer_size ;
00297   if(call_setsockopt(m_socket_id, SOL_SOCKET, SO_RCVBUF,
00298                     &L_max_buf_size, sizeof(L_max_buf_size))) {
00299     SOCKET_ERROR(1, "Unable to set socket rcvbuf");
00300   }
00301 
00302   // non blocking mode
00303   L_flags = call_fcntl(m_socket_id, F_GETFL , NULL);
00304   L_flags |= O_NONBLOCK;
00305   call_fcntl(m_socket_id, F_SETFL , L_flags);
00306 
00307 }
00308 
00309 C_SocketListen::C_SocketListen(C_SocketListen &P_Socket)
00310   : C_Socket(P_Socket) {
00311 
00312   m_source_addr_info = P_Socket.m_source_addr_info ;
00313   m_read_buf_size = P_Socket.m_read_buf_size ;
00314   m_segm_buf_size = P_Socket.m_segm_buf_size ;
00315 
00316 }
00317 
00318 C_SocketListen::C_SocketListen(T_SocketType P_type, 
00319                                T_pIpAddr    P_addr, 
00320                                int          P_channel_id,
00321                                size_t       P_read_buf_size,
00322                                size_t       P_segm_buf_size)   
00323   : C_Socket(P_type, P_channel_id) {
00324   SOCKET_DEBUG(0, "C_SocketListen::C_SocketListen() id=" << m_socket_id);
00325   m_source_addr_info = P_addr ;
00326   m_read_buf_size = P_read_buf_size ;
00327   m_segm_buf_size = P_segm_buf_size ;
00328 }
00329 
00330 
00331 C_SocketListen::~C_SocketListen() {
00332   SOCKET_DEBUG(0, "C_SocketListen::~C_SocketListen() id=" << m_socket_id);
00333 }
00334 
00335 size_t C_SocketListen::received_buffer (unsigned char  *P_data, 
00336                                         size_t          P_size_buf,
00337                                         struct timeval *P_time) {
00338   SOCKET_DEBUG(0, "C_SocketListen::received_buffer() id=" << m_socket_id);
00339   return (0); 
00340 }
00341 
00342 int C_SocketListen::_call_listen (int P_max) {
00343   return (call_listen(m_socket_id, P_max));
00344 }
00345 
00346 int C_SocketListen::_open (size_t P_buffer_size, 
00347                            C_ProtocolBinaryFrame *P_protocol) {
00348 
00349    int               L_rc          ; /* system calls return value storage */
00350 
00351    SOCKET_DEBUG(0, "C_SocketListen::_open()");
00352 
00353    L_rc = C_Socket::_open(get_domain(m_source_addr_info), 
00354                           P_buffer_size,
00355                           P_protocol) ;
00356 
00357    if (L_rc == 0) {
00358 
00359      /* bind the socket to the newly formed address */
00360      L_rc = call_bind(m_socket_id, 
00361                  (sockaddr *)(void *)&(m_source_addr_info->m_addr),
00362                  SOCKADDR_IN_SIZE(&(m_source_addr_info->m_addr)));
00363    /* check there was no error */
00364      if (L_rc) {
00365        SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
00366      } else {
00367        
00368        if (m_type == E_SOCKET_TCP_MODE) {
00369          /* ask the system to listen for incoming connections   */
00370          /* to the address we just bound. specify that up to            */
00371          /* 5 pending connection requests will be queued by the */
00372          /* system, if we are not directly awaiting them using  */
00373          /* the accept() system call, when they arrive.         */
00374          L_rc = _call_listen(5);
00375          
00376          /* check there was no error */
00377          if (L_rc) {
00378            SOCKET_ERROR(1, "listen [" << strerror(errno) << "]");
00379          }
00380        }
00381 
00382        m_state = E_SOCKET_STATE_READY ;
00383      }
00384    }
00385 
00386    return (L_rc);
00387   
00388 }
00389 
00390 C_Socket* C_SocketListen::create_socket_server(int *P_ret) {
00391   C_SocketServer* L_socket ;
00392   NEW_VAR(L_socket, C_SocketServer(this, m_channel_id, 
00393                                    m_read_buf_size, m_segm_buf_size));
00394   (*P_ret) = L_socket->_open(m_buffer_size, m_protocol) ;
00395   return (L_socket);
00396 }
00397 
00398 C_Socket* C_SocketListen::process_fd_set (fd_set           *P_rSet, 
00399                                           fd_set           *P_wSet,
00400                                           C_TransportEvent *P_event) {
00401 
00402   C_Socket        *L_socket = NULL ;
00403   int              L_ret ;
00404   
00405   SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() id=" << m_socket_id);
00406 
00407   if (FD_ISSET(m_socket_id, P_rSet)) {
00408     L_socket = create_socket_server (&L_ret) ;
00409     if (L_ret == 0) {
00410       SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() CNX");
00411       P_event->m_type = C_TransportEvent::E_TRANS_CONNECTION ;
00412       P_event->m_channel_id = m_channel_id ;
00413       P_event->m_id = L_socket->get_id() ;
00414     } else {
00415       SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() NOEVENT open failed");
00416       DELETE_VAR(L_socket);
00417       P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00418     }
00419   } else {
00420     SOCKET_DEBUG(0, "C_SocketListen::process_fd_set() NOEVENT");
00421     P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00422   }
00423 
00424   return (L_socket);
00425 }
00426 
00427 T_SockAddrStorage* C_SocketListen::get_source_address() {
00428   return(&(m_source_addr_info->m_addr));
00429 }
00430 
00431 T_SocketType C_SocketListen::get_trans_type() {
00432   return(m_type);
00433 }
00434 
00435 
00436 C_SocketServer::C_SocketServer (C_SocketServer& P_Socket) 
00437   : C_SocketWithData (P_Socket) {
00438   m_listen_sock = P_Socket.m_listen_sock;
00439   m_source_udp_addr_info = P_Socket.m_source_udp_addr_info;
00440 }
00441 
00442 C_SocketServer::C_SocketServer(C_SocketListen *P_listen, 
00443                                int P_channel_id,
00444                                size_t P_read_buf_size,
00445                                size_t P_segm_buf_size)
00446   : C_SocketWithData(P_channel_id, P_read_buf_size, P_segm_buf_size) {
00447   SOCKET_DEBUG(0, "C_SocketServer::C_SocketServer() id=" << m_socket_id);
00448   m_listen_sock = P_listen ;
00449   m_source_udp_addr_info = NULL ;
00450   m_type = m_listen_sock->get_trans_type();
00451 }
00452 
00453 C_SocketServer::C_SocketServer(T_SocketType P_type, 
00454                                T_pIpAddr    P_addr, 
00455                                int          P_channel_id,
00456                                size_t       P_read_buf_size,
00457                                size_t       P_segm_buf_size)
00458   : C_SocketWithData(P_type,
00459                      P_addr,
00460                      P_channel_id, 
00461                      P_read_buf_size, 
00462                      P_segm_buf_size) {
00463   m_listen_sock = NULL ;
00464   m_source_udp_addr_info = P_addr ;     
00465   SOCKET_DEBUG(0, "C_SocketServer::C_SocketServer() id=" << m_socket_id);
00466 }
00467 
00468 int C_SocketServer::_open_udp (size_t P_buffer_size, 
00469                                C_ProtocolBinaryFrame *P_protocol) {
00470 
00471    int               L_rc          ; /* system calls return value storage */
00472 
00473    SOCKET_DEBUG(0, "C_SocketServer::_open_udp()");
00474 
00475    L_rc = C_Socket::_open(get_domain(m_source_udp_addr_info), 
00476                           P_buffer_size,
00477                           P_protocol) ;
00478 
00479    if (L_rc == 0) {
00480 
00481      m_protocol = P_protocol ;
00482      
00483      m_buffer_size = P_buffer_size ;
00484      
00485      /* bind the socket to the newly formed address */
00486      L_rc = call_bind(m_socket_id, 
00487                  (sockaddr *)(void *)&(m_source_udp_addr_info->m_addr),
00488                  SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr)));
00489    /* check there was no error */
00490      if (L_rc) {
00491        SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
00492      } else {
00493         m_remote_sockaddr         = m_source_udp_addr_info->m_addr;
00494         m_len_remote_sockaddr     = SOCKADDR_IN_SIZE(&(m_source_udp_addr_info->m_addr));
00495         m_remote_sockaddr_ptr     = &m_remote_sockaddr ;
00496         m_len_remote_sockaddr_ptr = &m_len_remote_sockaddr ;
00497         m_state = E_SOCKET_STATE_READY ;
00498      }
00499    }
00500    return (L_rc);
00501 }
00502 
00503 C_SocketServer::~C_SocketServer() {
00504   SOCKET_DEBUG(0, "C_SocketServer::~C_SocketServer() id=" << m_socket_id);
00505 }
00506 
00507 int C_SocketServer::_open(size_t P_buffer_size, 
00508                           C_ProtocolBinaryFrame *P_protocol) {
00509 
00510   tool_socklen_t L_size   ;
00511   int            L_rc = 0 ;
00512 
00513   SOCKET_DEBUG(0, "C_SocketServer::_open()");
00514 
00515   L_size = SOCKADDR_IN_SIZE(m_listen_sock->get_source_address());
00516   memset(&m_accepted_addr, 0, L_size);
00517   
00518   m_socket_id = call_accept (m_listen_sock->get_id(), 
00519                              (sockaddr *)(void *)&m_accepted_addr,
00520                              &L_size);
00521   
00522 
00523   m_protocol = P_protocol ;
00524 
00525   m_buffer_size = P_buffer_size ;
00526 
00527   set_properties () ;
00528 
00529   if (m_socket_id < 0) {
00530     SOCKET_ERROR(0, "accept failed for listen [" << m_listen_sock->get_id()
00531                  << "] [" << strerror(errno) << "]");
00532     L_rc = -1 ;
00533   } else {
00534     m_state = E_SOCKET_STATE_READY ;
00535   }
00536 
00537   return (L_rc);
00538 }
00539 
00540 
00541 C_SocketClient::C_SocketClient(C_SocketClient& P_Socket) 
00542   : C_SocketWithData (P_Socket) {
00543 }
00544 
00545 C_SocketClient::C_SocketClient(T_SocketType P_type, 
00546                                T_pIpAddr    P_addr, 
00547                                int          P_channel_id,
00548                                size_t       P_read_buf_size,
00549                                size_t       P_segm_buf_size)
00550   : C_SocketWithData(P_type, P_addr, P_channel_id, 
00551                      P_read_buf_size, P_segm_buf_size) {
00552   SOCKET_DEBUG(0, "C_SocketClient::C_SocketClient() id=" << m_socket_id);
00553 }
00554 
00555 C_SocketClient::~C_SocketClient() {
00556   SOCKET_DEBUG(0, "C_SocketClient::~C_SocketClient() id=" << m_socket_id);
00557 }
00558 
00559 int C_SocketClient::_open(T_pOpenStatus  P_status,
00560                           size_t         P_buffer_size,
00561                           C_ProtocolBinaryFrame *P_protocol) {
00562 
00563   int             L_rc = 0 ;
00564   
00565   SOCKET_DEBUG(0, "C_SocketClient::_open()");
00566   L_rc = C_Socket::_open(get_domain(m_remote_addr_info), 
00567                          P_buffer_size,
00568                          P_protocol) ;
00569 
00570   if (L_rc == 0) {
00571 
00572     if (m_type == E_SOCKET_TCP_MODE) {
00573 
00574       L_rc = call_connect (m_socket_id, 
00575                            (struct sockaddr*)(void*)&(m_remote_addr_info->m_addr),
00576                            SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr))) ;
00577       if (L_rc) {
00578         if (errno != EINPROGRESS) {
00579           SOCKET_ERROR(1, "connect failed [" 
00580                        << L_rc << "][" 
00581                        << strerror(errno) << "]");
00582           *P_status = E_OPEN_FAILED ;
00583         } else {
00584           m_state = E_SOCKET_STATE_INPROGESS ;
00585           *P_status = E_OPEN_DELAYED ;
00586           L_rc = 0 ;
00587         }
00588         
00589       } else {
00590         m_state = E_SOCKET_STATE_READY ;
00591         *P_status = E_OPEN_OK ;
00592       }
00593     } else {
00594       L_rc = call_bind(m_socket_id, 
00595                        (sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
00596                        SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
00597      
00598        if (L_rc) {
00599         SOCKET_ERROR(1, "bind [" << strerror(errno) << "]");
00600        } else {
00601         m_remote_sockaddr         = m_remote_addr_info->m_addr;
00602         m_len_remote_sockaddr     = SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr));
00603         m_remote_sockaddr_ptr     = &m_remote_sockaddr ;
00604         m_len_remote_sockaddr_ptr = &m_len_remote_sockaddr ;
00605         
00606         m_state                   = E_SOCKET_STATE_READY ;
00607         *P_status                 = E_OPEN_OK ;
00608         }
00609     }
00610   }
00611   return (L_rc);
00612 }
00613 
00614 C_SocketWithData::C_SocketWithData(C_SocketWithData &P_Socket) 
00615   : C_Socket (P_Socket) {
00616 
00617   m_data_queue = P_Socket.m_data_queue ;
00618   m_remote_addr_info = P_Socket.m_remote_addr_info ;
00619   m_accepted_addr = P_Socket.m_accepted_addr ;
00620 
00621   m_read_buf_size = P_Socket.m_read_buf_size ;
00622   m_read_buf = P_Socket.m_read_buf      ;
00623   P_Socket.m_read_buf = NULL ;
00624 
00625   m_remote_sockaddr = P_Socket.m_remote_sockaddr     ; 
00626   m_len_remote_sockaddr = P_Socket.m_len_remote_sockaddr ;
00627 
00628   m_remote_sockaddr_ptr = P_Socket.m_remote_sockaddr_ptr     ; 
00629   m_len_remote_sockaddr_ptr = P_Socket.m_len_remote_sockaddr_ptr ;
00630 
00631   m_decode = P_Socket.m_decode   ;
00632   P_Socket.m_decode = NULL ;
00633   m_recv_msg_list = P_Socket.m_recv_msg_list ;
00634   P_Socket.m_recv_msg_list = NULL ;
00635   
00636 }
00637 
00638 
00639 C_SocketWithData::C_SocketWithData(int P_channel_id,
00640                                    size_t P_read_buf_size,
00641                                    size_t P_segm_buf_size) 
00642   : C_Socket (P_channel_id) {
00643   SOCKET_DEBUG(0, "C_SocketWithData::C_SocketWithData() id=" << m_socket_id);
00644   m_data_queue.clear();
00645   NEW_VAR(m_decode, C_DataDecode(P_segm_buf_size));
00646   NEW_VAR(m_recv_msg_list, T_RcvMsgCtxtList());
00647   m_recv_msg_list->clear();
00648 
00649   m_read_buf_size = P_read_buf_size ;
00650   ALLOC_TABLE(m_read_buf, char*, sizeof(char), m_read_buf_size);
00651 
00652 }
00653 
00654 C_SocketWithData::C_SocketWithData(T_SocketType P_type,
00655                                    T_pIpAddr    P_addr,
00656                                    int          P_channel_id,
00657                                    size_t       P_read_buf_size,
00658                                    size_t       P_segm_buf_size)
00659   : C_Socket (P_type, P_channel_id) {
00660   SOCKET_DEBUG(0, "C_SocketWithData::C_SocketWithData() id=" << m_socket_id);
00661   m_data_queue.clear();
00662   m_remote_addr_info = P_addr;
00663 
00664   NEW_VAR(m_decode, C_DataDecode(P_segm_buf_size));
00665   NEW_VAR(m_recv_msg_list, T_RcvMsgCtxtList());
00666   m_recv_msg_list->clear();
00667 
00668   m_read_buf_size = P_read_buf_size ;
00669   ALLOC_TABLE(m_read_buf, char*, sizeof(char), m_read_buf_size);
00670 
00671   m_remote_sockaddr_ptr     = NULL ;
00672   m_len_remote_sockaddr_ptr = NULL ;
00673 
00674   m_len_remote_sockaddr = SOCKADDR_IN_SIZE(&m_remote_sockaddr);
00675   memset(&m_remote_sockaddr, 0, m_len_remote_sockaddr);
00676 }
00677 
00678 C_pDataDecode C_SocketWithData::get_decode() {
00679   return (m_decode);
00680 }
00681 
00682 T_pRcvMsgCtxtList C_SocketWithData::get_list() {
00683   return (m_recv_msg_list);
00684 }
00685 
00686 C_SocketWithData::~C_SocketWithData() {
00687   SOCKET_DEBUG(0, "C_SocketWithData::~C_SocketWithData()");
00688   if (!m_data_queue.empty()) {
00689     m_data_queue.erase(m_data_queue.begin(), m_data_queue.end());
00690   }
00691   DELETE_VAR(m_decode);
00692   if (!m_recv_msg_list->empty()) {
00693     // to do delete message
00694     m_recv_msg_list->erase(m_recv_msg_list->begin(),
00695                            m_recv_msg_list->end());
00696   }
00697   DELETE_VAR(m_recv_msg_list);
00698 
00699   m_read_buf_size = 0 ;
00700   FREE_TABLE(m_read_buf);
00701 }
00702 
00703 int C_SocketWithData::_call_read() { 
00704   return (call_read(m_socket_id, m_read_buf, m_read_buf_size)) ;
00705 }
00706 
00707 
00708 C_Socket* C_SocketWithData::process_fd_ready(fd_set *P_rSet, 
00709                                              fd_set *P_wSet, 
00710                                              C_TransportEvent *P_event) {
00711   
00712   int             L_rc ;
00713   T_pDataRcv      L_data ;
00714   struct timezone L_timeZone ;             
00715 
00716   if (FD_ISSET(m_socket_id, P_rSet)) {
00717     if (m_type == E_SOCKET_TCP_MODE) {
00718       L_rc = _call_read(); 
00719     } else {
00720       L_rc = _read();
00721     }
00722     
00723     if (L_rc <= 0) {
00724       SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() CLOSED");
00725       P_event->m_type = C_TransportEvent::E_TRANS_CLOSED ;
00726       P_event->m_channel_id = m_channel_id ;
00727       P_event->m_id = m_socket_id ;
00728     } else {
00729       SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() RCV " << L_rc);
00730       
00731       ALLOC_VAR(L_data, T_pDataRcv, sizeof(T_DataRcv));
00732       gettimeofday(&(L_data->m_time), &L_timeZone);
00733       
00734       P_event->m_type = C_TransportEvent::E_TRANS_RECEIVED ;
00735       P_event->m_channel_id = m_channel_id ;
00736       P_event->m_id = m_socket_id ;
00737       L_data->m_size = L_rc ;
00738       ALLOC_TABLE(L_data->m_data, 
00739                   unsigned char*, 
00740                   sizeof(unsigned char*), 
00741                   L_rc);
00742       memcpy(L_data->m_data, m_read_buf, L_rc);
00743       m_data_queue.push_back(L_data);
00744     }
00745   } else {
00746     SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() NOEVENT");
00747     P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00748   }
00749   return (NULL);
00750 }
00751 
00752 C_Socket* C_SocketWithData::process_fd_in_progess(fd_set *P_rSet, 
00753                                                   fd_set *P_wSet, 
00754                                                   C_TransportEvent *P_event) {
00755   int             L_sock_opt ;
00756   socklen_t       L_opt_len ;
00757 
00758   L_opt_len = sizeof (L_sock_opt);
00759   
00760   if (FD_ISSET(m_socket_id, P_wSet)) {
00761     if (getsockopt(m_socket_id, SOL_SOCKET, SO_ERROR, (void *)&L_sock_opt,
00762                    &L_opt_len) == -1) {
00763       SOCKET_ERROR(1, "getsockopt(SO_ERROR) failed");
00764     }
00765     if (L_sock_opt == 0) {
00766       m_state = E_SOCKET_STATE_READY ;
00767       P_event->m_type = C_TransportEvent::E_TRANS_OPEN ;
00768       P_event->m_channel_id = m_channel_id ;
00769       P_event->m_id = m_socket_id ;
00770     } else {
00771       P_event->m_type = C_TransportEvent::E_TRANS_OPEN_FAILED ;
00772       P_event->m_channel_id = m_channel_id ;
00773       P_event->m_id = m_socket_id ;
00774       SOCKET_ERROR(1, "delayed operation error for ["
00775                    << m_socket_id << "]");
00776     }
00777   }
00778   return (NULL);
00779 }
00780 
00781 
00782 C_Socket* C_SocketWithData::process_fd_set (fd_set* P_rSet,
00783                                             fd_set* P_wSet,
00784                                             C_TransportEvent *P_event) {
00785 
00786   C_Socket* L_socket = NULL ;
00787 
00788   SOCKET_DEBUG(0, "C_SocketWithData::process_fd_set() id=" << m_socket_id);
00789 
00790   switch (m_state) {
00791 
00792   case E_SOCKET_STATE_READY:
00793 
00794     L_socket = process_fd_ready(P_rSet, P_wSet, P_event);
00795     break ;
00796 
00797   case E_SOCKET_STATE_INPROGESS:
00798 
00799     L_socket = process_fd_in_progess(P_rSet, P_wSet, P_event);
00800     break ;
00801 
00802   case E_SOCKET_STATE_NOT_READY:
00803     break ;
00804 
00805   }
00806 
00807   return (L_socket);
00808 }
00809 
00810 size_t C_SocketWithData::received_buffer(unsigned char *P_data, 
00811                                          size_t          P_size_buf,
00812                                          struct timeval *P_time) {
00813 
00814   size_t                  L_size = 0 ;
00815   T_DataRcvList::iterator L_it ;
00816   T_pDataRcv              L_data ;
00817   
00818   SOCKET_DEBUG(0, "C_SocketWithData::received_buffer() id=" << m_socket_id);
00819 
00820   if (!m_data_queue.empty()) {
00821     L_it = m_data_queue.begin();
00822     L_data = *L_it ;
00823     m_data_queue.erase(L_it);
00824     L_size = L_data->m_size ;
00825     SOCKET_DEBUG(0, "C_SocketWithData::received_buffer() size=" << L_size);
00826     memcpy(P_data, L_data->m_data, L_size);
00827     //    memmove(P_data, L_data->m_data, L_size);
00828     //    SOCKET_DEBUG(0, "C_SocketWithData::received_buffer() L_buf=" 
00829     //           << L_data->m_data);
00830     *P_time = L_data->m_time ;
00831     FREE_TABLE(L_data->m_data);
00832     FREE_VAR(L_data) ;
00833   }
00834 
00835   SOCKET_DEBUG(0, "C_SocketWithData::received_buffer() return=" 
00836                << L_size);
00837   return (L_size);
00838 }
00839 
00840 int C_SocketServer::_read () {
00841   return (call_recvfrom(m_socket_id, 
00842                         m_read_buf, 
00843                         m_read_buf_size,
00844                         0,
00845                         (sockaddr *)(void *)m_remote_sockaddr_ptr, 
00846                         m_len_remote_sockaddr_ptr));
00847 }
00848 
00849 int C_SocketClient::_read () {
00850   return (call_recvfrom(m_socket_id, 
00851                         m_read_buf, 
00852                         m_read_buf_size,
00853                         0,
00854                         NULL,
00855                         NULL));
00856 }
00857 
00858 
00859 // End of file

Generated on Wed Mar 7 14:44:58 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002