net_socket.cpp
Go to the documentation of this file.
00001 /*
00002  *  RoboPeak Project
00003  *  HAL Layer - Socket Interface
00004  *  Copyright 2009 - 2013 RoboPeak Project
00005  *
00006  *  POXIS Implementation
00007  */
00008 
00009 
00010 #include "sdkcommon.h"
00011 #include "../../hal/socket.h"
00012 
00013 #include <sys/socket.h>
00014 #include <netinet/in.h>
00015 #include <netinet/tcp.h>
00016 #include <arpa/inet.h>
00017 #include <netdb.h>
00018 
00019 namespace rp{ namespace net {
00020 
00021 
00022 static inline int _halAddrTypeToOSType(SocketAddress::address_type_t type) 
00023 {
00024     switch (type) {
00025         case SocketAddress::ADDRESS_TYPE_INET:
00026             return AF_INET;
00027         case SocketAddress::ADDRESS_TYPE_INET6:
00028             return AF_INET6;
00029         case SocketAddress::ADDRESS_TYPE_UNSPEC:
00030             return AF_UNSPEC;
00031 
00032         default:
00033             assert(!"should not reach here");
00034             return AF_UNSPEC;
00035     }
00036 }
00037 
00038 
00039 SocketAddress::SocketAddress() 
00040 {
00041     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00042     memset(_platform_data, 0, sizeof(sockaddr_storage));
00043     
00044     reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00045 }
00046 
00047 SocketAddress::SocketAddress(const SocketAddress & src)
00048 {
00049     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00050     memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00051 }
00052 
00053 
00054 
00055 SocketAddress::SocketAddress(const char * addrString, int port, SocketAddress::address_type_t type)
00056 {
00057     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00058     memset(_platform_data, 0, sizeof(sockaddr_storage));
00059     
00060     // default to ipv4 in case the following operation fails
00061     reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00062 
00063     setAddressFromString(addrString, type);
00064     setPort(port);
00065 }
00066 
00067 SocketAddress::SocketAddress(void * platform_data)
00068  : _platform_data(platform_data)
00069 {}
00070 
00071 SocketAddress & SocketAddress::operator = (const SocketAddress &src)
00072 {
00073     memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00074     return *this;
00075 }
00076 
00077 
00078 SocketAddress::~SocketAddress()
00079 {
00080     delete reinterpret_cast<sockaddr_storage *>(_platform_data);
00081 }
00082 
00083 SocketAddress::address_type_t SocketAddress::getAddressType() const
00084 {
00085     switch(reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family) {
00086         case AF_INET:
00087             return ADDRESS_TYPE_INET;
00088         case AF_INET6:
00089             return ADDRESS_TYPE_INET6;
00090         default:
00091             assert(!"should not reach here");
00092             return ADDRESS_TYPE_INET;
00093     }
00094 }
00095 
00096 int SocketAddress::getPort() const
00097 {
00098     switch (getAddressType()) {
00099         case ADDRESS_TYPE_INET:
00100             return (int)ntohs(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_port);
00101         case ADDRESS_TYPE_INET6:
00102             return (int)ntohs(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_port);
00103         default:
00104             return 0;
00105     }
00106 }
00107 
00108 u_result SocketAddress::setPort(int port)
00109 {
00110     switch (getAddressType()) {
00111         case ADDRESS_TYPE_INET:
00112             reinterpret_cast<sockaddr_in *>(_platform_data)->sin_port = htons((short)port);
00113             break;
00114         case ADDRESS_TYPE_INET6:
00115             reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_port = htons((short)port);
00116             break;
00117         default:
00118             return RESULT_OPERATION_FAIL;
00119     }
00120     return RESULT_OK;
00121 }
00122 
00123 u_result SocketAddress::setAddressFromString(const char * address_string,  SocketAddress::address_type_t type)
00124 {
00125     int ans = 0;
00126     int prevPort = getPort();
00127     switch (type) {
00128         case ADDRESS_TYPE_INET:
00129             reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00130             ans = inet_pton(AF_INET, 
00131                             address_string, 
00132                             &reinterpret_cast<sockaddr_in *>(_platform_data)->sin_addr);
00133         break;
00134 
00135 
00136         case ADDRESS_TYPE_INET6:
00137             
00138             reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET6;
00139             ans = inet_pton(AF_INET6, 
00140                             address_string, 
00141                             &reinterpret_cast<sockaddr_in6  *>(_platform_data)->sin6_addr);
00142         break;
00143 
00144         default:
00145             return RESULT_INVALID_DATA;
00146 
00147     }
00148     setPort(prevPort);
00149 
00150     return ans<=0?RESULT_INVALID_DATA:RESULT_OK;
00151 }
00152 
00153 
00154 u_result SocketAddress::getAddressAsString(char * buffer, size_t buffersize) const
00155 {
00156     int net_family = reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family;
00157     const char *ans = NULL;
00158     switch (net_family) {
00159         case AF_INET:
00160             ans = inet_ntop(net_family, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr,
00161                             buffer, buffersize);
00162         break;
00163 
00164         case AF_INET6:
00165             ans = inet_ntop(net_family, &reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr,
00166                             buffer, buffersize);
00167 
00168         break;
00169     }
00170     return ans<=0?RESULT_OPERATION_FAIL:RESULT_OK;
00171 }
00172 
00173 
00174 
00175 size_t SocketAddress::LoopUpHostName(const char * hostname, const char * sevicename, std::vector<SocketAddress> &addresspool , bool performDNS, SocketAddress::address_type_t type)
00176 {
00177     struct addrinfo hints;
00178     struct addrinfo *result;
00179     int ans;
00180 
00181     memset(&hints, 0, sizeof(struct addrinfo));
00182     hints.ai_family = _halAddrTypeToOSType(type);
00183     hints.ai_flags = AI_PASSIVE;
00184 
00185     if (!performDNS) {
00186         hints.ai_family |= AI_NUMERICSERV | AI_NUMERICHOST;
00187     
00188     }
00189 
00190     ans = getaddrinfo(hostname, sevicename, &hints, &result);
00191 
00192     addresspool.clear();
00193 
00194     if (ans != 0) {
00195         // hostname loopup failed
00196         return 0;
00197     }
00198 
00199     
00200     for (struct addrinfo * cursor = result; cursor != NULL; cursor = cursor->ai_next) {
00201         if (cursor->ai_family == ADDRESS_TYPE_INET || cursor->ai_family == ADDRESS_TYPE_INET6) {
00202             sockaddr_storage * storagebuffer = new sockaddr_storage;
00203             assert(sizeof(sockaddr_storage) >= cursor->ai_addrlen);
00204             memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
00205             addresspool.push_back(SocketAddress(storagebuffer));
00206         }
00207     }
00208 
00209     
00210     freeaddrinfo(result);
00211 
00212     return addresspool.size();
00213 }
00214 
00215 
00216 u_result SocketAddress::getRawAddress(_u8 * buffer, size_t bufferSize) const
00217 {
00218      switch (getAddressType()) {
00219         case ADDRESS_TYPE_INET:
00220             if (bufferSize < sizeof(in_addr::s_addr)) return RESULT_INSUFFICIENT_MEMORY;
00221 
00222             memcpy(buffer, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr, sizeof(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr));
00223 
00224             
00225             break;
00226         case ADDRESS_TYPE_INET6:
00227             if (bufferSize < sizeof(in6_addr::s6_addr)) return RESULT_INSUFFICIENT_MEMORY;
00228             memcpy(buffer, reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr, sizeof(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr));
00229 
00230             break;
00231         default:
00232             return RESULT_OPERATION_FAIL;
00233     }
00234     return RESULT_OK;
00235 }
00236 
00237 
00238 void SocketAddress::setLoopbackAddress(SocketAddress::address_type_t type)
00239 {
00240 
00241     int prevPort = getPort();
00242     switch (type) {
00243         case ADDRESS_TYPE_INET:
00244             {
00245                 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00246                 addrv4->sin_family = AF_INET;
00247                 addrv4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00248             }
00249             break;
00250         case ADDRESS_TYPE_INET6:
00251             {
00252                 sockaddr_in6  * addrv6 = reinterpret_cast<sockaddr_in6  *>(_platform_data);
00253                 addrv6->sin6_family = AF_INET6;
00254                 addrv6->sin6_addr = in6addr_loopback;
00255 
00256             }
00257             break;
00258         default:
00259             return;
00260     }
00261 
00262     setPort(prevPort);
00263 }
00264 
00265 void SocketAddress::setBroadcastAddressIPv4()
00266 {
00267 
00268     int prevPort = getPort();
00269     sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00270     addrv4->sin_family = AF_INET;
00271     addrv4->sin_addr.s_addr = htonl(INADDR_BROADCAST);
00272     setPort(prevPort);
00273 
00274 }
00275 
00276 void SocketAddress::setAnyAddress(SocketAddress::address_type_t type)
00277 {
00278     int prevPort = getPort();
00279     switch (type) {
00280         case ADDRESS_TYPE_INET:
00281             {
00282                 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00283                 addrv4->sin_family = AF_INET;
00284                 addrv4->sin_addr.s_addr = htonl(INADDR_ANY);
00285             }
00286             break;
00287         case ADDRESS_TYPE_INET6:
00288             {
00289                 sockaddr_in6  * addrv6 = reinterpret_cast<sockaddr_in6  *>(_platform_data);
00290                 addrv6->sin6_family = AF_INET6;
00291                 addrv6->sin6_addr = in6addr_any;
00292 
00293             }
00294             break;
00295         default:
00296             return;
00297     }
00298 
00299     setPort(prevPort);
00300 
00301 
00302 }
00303 
00304 
00305 }}
00306 
00307 
00308 
00310 
00311 
00312 namespace rp { namespace arch { namespace net{ 
00313 
00314 using namespace rp::net;
00315 
00316 class _single_thread StreamSocketImpl : public StreamSocket
00317 {
00318 public:
00319 
00320     StreamSocketImpl(int fd)
00321         : _socket_fd(fd)
00322     {
00323         assert(fd>=0);
00324         int bool_true = 1;
00325         ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR , (char *)&bool_true, sizeof(bool_true) );
00326 
00327         enableNoDelay(true);
00328         this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00329     }
00330 
00331     virtual ~StreamSocketImpl() 
00332     {
00333         close(_socket_fd);
00334     }
00335 
00336     virtual void dispose()
00337     {
00338         delete this;
00339     }
00340 
00341 
00342     virtual u_result bind(const SocketAddress & localaddr)
00343     {
00344         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00345         assert(addr);
00346         int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00347         if (ans) {
00348             return RESULT_OPERATION_FAIL;
00349         } else {
00350             return RESULT_OK;
00351         }
00352     }
00353 
00354     virtual u_result getLocalAddress(SocketAddress & localaddr)
00355     {
00356         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData())); //donnot do this at home...
00357         assert(addr);
00358 
00359         size_t actualsize =  sizeof(sockaddr_storage);
00360         int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00361 
00362         assert(actualsize <= sizeof(sockaddr_storage));
00363         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00364 
00365         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00366     }
00367 
00368     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00369     {
00370         int ans;
00371         timeval tv;
00372         tv.tv_sec = timeout / 1000; 
00373         tv.tv_usec = (timeout % 1000) * 1000; 
00374 
00375         if (msk & SOCKET_DIR_RD) {
00376              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00377              if (ans) return RESULT_OPERATION_FAIL;
00378         }
00379 
00380         if (msk & SOCKET_DIR_WR) {
00381              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00382              if (ans) return RESULT_OPERATION_FAIL;
00383         }
00384 
00385         return RESULT_OK;
00386     }
00387   
00388     virtual u_result connect(const SocketAddress & pairAddress)
00389     {
00390         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
00391         int ans = ::connect(_socket_fd, addr, sizeof(sockaddr_storage));
00392         if (!ans) return RESULT_OK;
00393 
00394 
00395         switch (errno) {
00396             case EAFNOSUPPORT:
00397                 return RESULT_OPERATION_NOT_SUPPORT;
00398 #if 0
00399             case EINPROGRESS:
00400                 return RESULT_OK; //treat async connection as good status
00401 #endif
00402             case ETIMEDOUT:
00403                 return RESULT_OPERATION_TIMEOUT;
00404             default:
00405                 return RESULT_OPERATION_FAIL;
00406         }
00407     }
00408       
00409     virtual u_result listen(int backlog)
00410     {
00411         int ans = ::listen( _socket_fd,   backlog);
00412 
00413         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00414     }
00415 
00416     virtual StreamSocket * accept(SocketAddress * pairAddress) 
00417     {
00418         size_t addrsize;
00419         addrsize = sizeof(sockaddr_storage);
00420         int pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
00421             , (socklen_t*)&addrsize);
00422 
00423         if (pair_socket>=0) {
00424             return new StreamSocketImpl(pair_socket);
00425         } else {
00426             return NULL;
00427         }
00428     }
00429 
00430     virtual u_result waitforIncomingConnection(_u32 timeout)
00431     {
00432         return waitforData(timeout);
00433     }
00434 
00435     virtual u_result send(const void * buffer, size_t len) 
00436     {
00437         size_t ans = ::send( _socket_fd, buffer, len, MSG_NOSIGNAL);
00438         if (ans == (int)len) {
00439             return RESULT_OK;
00440         } else {
00441             switch (errno) {
00442                 case EAGAIN:
00443 #if EWOULDBLOCK!=EAGAIN
00444                 case EWOULDBLOCK:
00445 #endif
00446                     return RESULT_OPERATION_TIMEOUT;
00447                 default:
00448                     return RESULT_OPERATION_FAIL;
00449             }
00450         }
00451         
00452     }
00453 
00454 
00455     virtual u_result recv(void *buf, size_t len, size_t & recv_len)
00456     {
00457         size_t ans = ::recv( _socket_fd, buf, len, 0);
00458         if (ans == (size_t)-1) {
00459             recv_len = 0;  
00460 
00461             switch (errno) {
00462                 case EAGAIN:
00463 #if EWOULDBLOCK!=EAGAIN
00464                 case EWOULDBLOCK:
00465 #endif
00466                     return RESULT_OPERATION_TIMEOUT;
00467                 default:
00468                     return RESULT_OPERATION_FAIL;
00469             }
00470 
00471             
00472 
00473         } else {
00474             recv_len = ans;
00475             return RESULT_OK;
00476         }
00477     }
00478 
00479 #if 0
00480     virtual u_result recvNoWait(void *buf, size_t len, size_t & recv_len)
00481     {
00482         size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
00483         if (ans == (size_t)-1) {
00484             recv_len = 0;  
00485             if (errno == EAGAIN || errno == EWOULDBLOCK) {
00486                 return RESULT_OK; 
00487             } else {
00488                 return RESULT_OPERATION_FAIL;
00489             }
00490 
00491 
00492         } else {
00493             recv_len = ans;
00494             return RESULT_OK;
00495         }
00496 
00497     }
00498 #endif
00499 
00500     virtual u_result getPeerAddress(SocketAddress & peerAddr)
00501     {
00502         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData())); //donnot do this at home...
00503         assert(addr);
00504         size_t actualsize =  sizeof(sockaddr_storage);
00505         int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
00506 
00507         assert(actualsize <=  sizeof(sockaddr_storage));
00508         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00509 
00510         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00511 
00512     }
00513 
00514     virtual u_result shutdown(socket_direction_mask mask)
00515     {
00516         int shutdw_opt ;
00517 
00518         switch (mask) {
00519             case SOCKET_DIR_RD:
00520                 shutdw_opt = SHUT_RD;
00521                 break;
00522             case SOCKET_DIR_WR:
00523                 shutdw_opt = SHUT_WR;
00524                 break;
00525             case SOCKET_DIR_BOTH:
00526             default:
00527                 shutdw_opt = SHUT_RDWR;
00528         }
00529 
00530         int ans = ::shutdown(_socket_fd, shutdw_opt);
00531         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00532     }
00533 
00534     virtual u_result enableKeepAlive(bool enable)
00535     {
00536         int bool_true = enable?1:0;
00537         return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , &bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00538     }
00539 
00540     virtual u_result enableNoDelay(bool enable ) 
00541     {
00542         int bool_true = enable?1:0;
00543         return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY,&bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00544     }
00545 
00546     virtual u_result waitforSent(_u32 timeout ) 
00547     {
00548         fd_set wrset;
00549         FD_ZERO(&wrset);
00550         FD_SET(_socket_fd, &wrset);
00551 
00552         timeval tv;
00553         tv.tv_sec = timeout / 1000;
00554         tv.tv_usec = (timeout % 1000) * 1000;
00555         int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00556 
00557         switch (ans) {
00558             case 1:
00559                 // fired
00560                 return RESULT_OK;
00561             case 0:
00562                 // timeout
00563                 return RESULT_OPERATION_TIMEOUT;
00564             default:
00565                 delay(0); //relax cpu
00566                 return RESULT_OPERATION_FAIL;
00567         }
00568     }
00569 
00570     virtual u_result waitforData(_u32 timeout )
00571     {
00572         fd_set rdset;
00573         FD_ZERO(&rdset);
00574         FD_SET(_socket_fd, &rdset);
00575 
00576         timeval tv;
00577         tv.tv_sec = timeout / 1000;
00578         tv.tv_usec = (timeout % 1000) * 1000;
00579         int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00580 
00581         switch (ans) {
00582             case 1:
00583                 // fired
00584                 return RESULT_OK;
00585             case 0:
00586                 // timeout
00587                 return RESULT_OPERATION_TIMEOUT;
00588             default:
00589                 delay(0); //relax cpu
00590                 return RESULT_OPERATION_FAIL;
00591         }
00592     }
00593 
00594 protected:
00595     int  _socket_fd;
00596 
00597 
00598 };
00599 
00600 
00601 class _single_thread DGramSocketImpl : public DGramSocket
00602 {
00603 public:
00604 
00605     DGramSocketImpl(int fd)
00606         : _socket_fd(fd)
00607     {
00608         assert(fd>=0);
00609         int bool_true = 1;
00610         ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, sizeof(bool_true) );
00611         setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00612     }
00613 
00614     virtual ~DGramSocketImpl() 
00615     {
00616         close(_socket_fd);
00617     }
00618 
00619     virtual void dispose()
00620     {
00621         delete this;
00622     }
00623 
00624 
00625     virtual u_result bind(const SocketAddress & localaddr)
00626     {
00627         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00628         assert(addr);
00629         int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00630         if (ans) {
00631             return RESULT_OPERATION_FAIL;
00632         } else {
00633             return RESULT_OK;
00634         }
00635     }
00636 
00637     virtual u_result getLocalAddress(SocketAddress & localaddr)
00638     {
00639         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData()))); //donnot do this at home...
00640         assert(addr);
00641 
00642         size_t actualsize =  sizeof(sockaddr_storage);
00643         int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00644 
00645         assert(actualsize <= sizeof(sockaddr_storage));
00646         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00647 
00648         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00649     }
00650 
00651     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00652     {
00653         int ans;
00654         timeval tv;
00655         tv.tv_sec = timeout / 1000; 
00656         tv.tv_usec = (timeout % 1000) * 1000; 
00657 
00658         if (msk & SOCKET_DIR_RD) {
00659              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00660              if (ans) return RESULT_OPERATION_FAIL;
00661         }
00662 
00663         if (msk & SOCKET_DIR_WR) {
00664              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00665              if (ans) return RESULT_OPERATION_FAIL;
00666         }
00667 
00668         return RESULT_OK;
00669     }
00670   
00671 
00672     virtual u_result waitforSent(_u32 timeout ) 
00673     {
00674         fd_set wrset;
00675         FD_ZERO(&wrset);
00676         FD_SET(_socket_fd, &wrset);
00677 
00678         timeval tv;
00679         tv.tv_sec = timeout / 1000;
00680         tv.tv_usec = (timeout % 1000) * 1000;
00681         int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00682 
00683         switch (ans) {
00684             case 1:
00685                 // fired
00686                 return RESULT_OK;
00687             case 0:
00688                 // timeout
00689                 return RESULT_OPERATION_TIMEOUT;
00690             default:
00691                 delay(0); //relax cpu
00692                 return RESULT_OPERATION_FAIL;
00693         }
00694     }
00695 
00696     virtual u_result waitforData(_u32 timeout )
00697     {
00698         fd_set rdset;
00699         FD_ZERO(&rdset);
00700         FD_SET(_socket_fd, &rdset);
00701 
00702         timeval tv;
00703         tv.tv_sec = timeout / 1000;
00704         tv.tv_usec = (timeout % 1000) * 1000;
00705         int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00706 
00707         switch (ans) {
00708             case 1:
00709                 // fired
00710                 return RESULT_OK;
00711             case 0:
00712                 // timeout
00713                 return RESULT_OPERATION_TIMEOUT;
00714             default:
00715                 delay(0); //relax cpu
00716                 return RESULT_OPERATION_FAIL;
00717         }
00718     }
00719 
00720     virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
00721     {
00722         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
00723         assert(addr);
00724         size_t ans = ::sendto( _socket_fd, buffer, len, 0, addr, sizeof(sockaddr_storage));
00725         if (ans != (size_t)-1) {
00726             assert(ans == (int)len);
00727             return RESULT_OK;
00728         } else {
00729             switch (errno) {
00730                 case EAGAIN:
00731 #if EWOULDBLOCK!=EAGAIN
00732                 case EWOULDBLOCK:
00733 #endif
00734                     return RESULT_OPERATION_TIMEOUT;
00735 
00736                 case EMSGSIZE:
00737                     return RESULT_INVALID_DATA;
00738                 default:
00739                     return RESULT_OPERATION_FAIL;
00740             }
00741         
00742         }
00743 
00744     }
00745 
00746 
00747     virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00748     {
00749         struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00750         size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00751 
00752         size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
00753         if (ans == (size_t)-1) {
00754             recv_len = 0;  
00755             switch (errno) {
00756                 case EAGAIN:
00757 #if EWOULDBLOCK!=EAGAIN
00758                 case EWOULDBLOCK:
00759 #endif
00760                     return RESULT_OPERATION_TIMEOUT;
00761                 default:
00762                     return RESULT_OPERATION_FAIL;
00763             }
00764 
00765         } else {
00766             recv_len = ans;
00767             return RESULT_OK;
00768         }
00769 
00770     }
00771 
00772 #if 0
00773     virtual u_result recvFromNoWait(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00774     {
00775         struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00776         size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00777 
00778 
00779         size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
00780 
00781         if (ans == (size_t)-1) {
00782             recv_len = 0;  
00783             if (errno == EAGAIN || errno == EWOULDBLOCK) {
00784                 return RESULT_OK; 
00785             } else {
00786                 return RESULT_OPERATION_FAIL;
00787             }
00788 
00789 
00790         } else {
00791             recv_len = ans;
00792             return RESULT_OK;
00793         }
00794 
00795     }
00796 #endif
00797     
00798 protected:
00799     int  _socket_fd;
00800 
00801 };
00802 
00803 
00804 }}}
00805 
00806 
00807 namespace rp { namespace net{ 
00808 
00809 
00810 static inline int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
00811 {
00812     switch (family) {
00813         case SocketBase::SOCKET_FAMILY_INET:
00814             return AF_INET;
00815         case SocketBase::SOCKET_FAMILY_INET6:
00816             return AF_INET6;
00817         case SocketBase::SOCKET_FAMILY_RAW:
00818             return AF_PACKET;
00819         default:
00820             assert(!"should not reach here");
00821             return AF_INET; // force treating as IPv4 in release mode
00822     }
00823 
00824 }
00825 
00826 StreamSocket * StreamSocket::CreateSocket(SocketBase::socket_family_t family)
00827 {
00828     if (family == SOCKET_FAMILY_RAW) return NULL;
00829 
00830 
00831     int socket_family = _socketHalFamilyToOSFamily(family);
00832     int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
00833     if (socket_fd == -1) return NULL;
00834 
00835     StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
00836     return newborn;
00837 
00838 }
00839 
00840 
00841 DGramSocket * DGramSocket::CreateSocket(SocketBase::socket_family_t family)
00842 {
00843     int socket_family = _socketHalFamilyToOSFamily(family);
00844 
00845 
00846     int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
00847     if (socket_fd == -1) return NULL;
00848 
00849     DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
00850     return newborn;
00851 
00852 }
00853 
00854 
00855 }}
00856 


rplidar_ros
Author(s):
autogenerated on Mon Mar 18 2019 02:34:23