net_socket.cpp
Go to the documentation of this file.
00001 /*
00002  *  RoboPeak Project
00003  *  HAL Layer - Socket Interface
00004  *  Copyright 2018 RoboPeak Project
00005  *
00006  *  macOS 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?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_t)) 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)) 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         ::setsockopt( _socket_fd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&bool_true, sizeof(bool_true));
00327 
00328         enableNoDelay(true);
00329         this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00330     }
00331 
00332     virtual ~StreamSocketImpl() 
00333     {
00334         close(_socket_fd);
00335     }
00336 
00337     virtual void dispose()
00338     {
00339         delete this;
00340     }
00341 
00342 
00343     virtual u_result bind(const SocketAddress & localaddr)
00344     {
00345         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00346         assert(addr);
00347         int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00348         if (ans) {
00349             return RESULT_OPERATION_FAIL;
00350         } else {
00351             return RESULT_OK;
00352         }
00353     }
00354 
00355     virtual u_result getLocalAddress(SocketAddress & localaddr)
00356     {
00357         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData())); //donnot do this at home...
00358         assert(addr);
00359 
00360         size_t actualsize =  sizeof(sockaddr_storage);
00361         int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00362 
00363         assert(actualsize <= sizeof(sockaddr_storage));
00364         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00365 
00366         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00367     }
00368 
00369     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00370     {
00371         int ans;
00372         timeval tv;
00373         tv.tv_sec = timeout / 1000; 
00374         tv.tv_usec = (timeout % 1000) * 1000; 
00375 
00376         if (msk & SOCKET_DIR_RD) {
00377              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00378              if (ans) return RESULT_OPERATION_FAIL;
00379         }
00380 
00381         if (msk & SOCKET_DIR_WR) {
00382              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00383              if (ans) return RESULT_OPERATION_FAIL;
00384         }
00385 
00386         return RESULT_OK;
00387     }
00388   
00389     virtual u_result connect(const SocketAddress & pairAddress)
00390     {
00391         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
00392         int ans = ::connect(_socket_fd, addr, sizeof(sockaddr_storage));
00393         if (!ans) return RESULT_OK;
00394 
00395 
00396         switch (errno) {
00397             case EAFNOSUPPORT:
00398                 return RESULT_OPERATION_NOT_SUPPORT;
00399 #if 0
00400             case EINPROGRESS:
00401                 return RESULT_OK; //treat async connection as good status
00402 #endif
00403             case ETIMEDOUT:
00404                 return RESULT_OPERATION_TIMEOUT;
00405             default:
00406                 return RESULT_OPERATION_FAIL;
00407         }
00408     }
00409       
00410     virtual u_result listen(int backlog)
00411     {
00412         int ans = ::listen( _socket_fd,   backlog);
00413 
00414         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00415     }
00416 
00417     virtual StreamSocket * accept(SocketAddress * pairAddress) 
00418     {
00419         size_t addrsize;
00420         addrsize = sizeof(sockaddr_storage);
00421         int pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
00422             , (socklen_t*)&addrsize);
00423 
00424         if (pair_socket>=0) {
00425             return new StreamSocketImpl(pair_socket);
00426         } else {
00427             return NULL;
00428         }
00429     }
00430 
00431     virtual u_result waitforIncomingConnection(_u32 timeout)
00432     {
00433         return waitforData(timeout);
00434     }
00435 
00436     virtual u_result send(const void * buffer, size_t len) 
00437     {
00438         size_t ans = ::send( _socket_fd, buffer, len, 0);
00439         if (ans == (int)len) {
00440             return RESULT_OK;
00441         } else {
00442             switch (errno) {
00443                 case EAGAIN:
00444 #if EWOULDBLOCK!=EAGAIN
00445                 case EWOULDBLOCK:
00446 #endif
00447                     return RESULT_OPERATION_TIMEOUT;
00448                 default:
00449                     return RESULT_OPERATION_FAIL;
00450             }
00451         }
00452         
00453     }
00454 
00455 
00456     virtual u_result recv(void *buf, size_t len, size_t & recv_len)
00457     {
00458         size_t ans = ::recv( _socket_fd, buf, len, 0);
00459         if (ans == (size_t)-1) {
00460             recv_len = 0;  
00461 
00462             switch (errno) {
00463                 case EAGAIN:
00464 #if EWOULDBLOCK!=EAGAIN
00465                 case EWOULDBLOCK:
00466 #endif
00467                     return RESULT_OPERATION_TIMEOUT;
00468                 default:
00469                     return RESULT_OPERATION_FAIL;
00470             }
00471 
00472             
00473 
00474         } else {
00475             recv_len = ans;
00476             return RESULT_OK;
00477         }
00478     }
00479 
00480 #if 0
00481     virtual u_result recvNoWait(void *buf, size_t len, size_t & recv_len)
00482     {
00483         size_t ans = ::recv( _socket_fd, buf, len, MSG_DONTWAIT);
00484         if (ans == (size_t)-1) {
00485             recv_len = 0;  
00486             if (errno == EAGAIN || errno == EWOULDBLOCK) {
00487                 return RESULT_OK; 
00488             } else {
00489                 return RESULT_OPERATION_FAIL;
00490             }
00491 
00492 
00493         } else {
00494             recv_len = ans;
00495             return RESULT_OK;
00496         }
00497 
00498     }
00499 #endif
00500 
00501     virtual u_result getPeerAddress(SocketAddress & peerAddr)
00502     {
00503         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData())); //donnot do this at home...
00504         assert(addr);
00505         size_t actualsize =  sizeof(sockaddr_storage);
00506         int ans = ::getpeername(_socket_fd, addr, (socklen_t*)&actualsize);
00507 
00508         assert(actualsize <=  sizeof(sockaddr_storage));
00509         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00510 
00511         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00512 
00513     }
00514 
00515     virtual u_result shutdown(socket_direction_mask mask)
00516     {
00517         int shutdw_opt ;
00518 
00519         switch (mask) {
00520             case SOCKET_DIR_RD:
00521                 shutdw_opt = SHUT_RD;
00522                 break;
00523             case SOCKET_DIR_WR:
00524                 shutdw_opt = SHUT_WR;
00525                 break;
00526             case SOCKET_DIR_BOTH:
00527             default:
00528                 shutdw_opt = SHUT_RDWR;
00529         }
00530 
00531         int ans = ::shutdown(_socket_fd, shutdw_opt);
00532         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00533     }
00534 
00535     virtual u_result enableKeepAlive(bool enable)
00536     {
00537         int bool_true = enable?1:0;
00538         return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , &bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00539     }
00540 
00541     virtual u_result enableNoDelay(bool enable ) 
00542     {
00543         int bool_true = enable?1:0;
00544         return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY,&bool_true, sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00545     }
00546 
00547     virtual u_result waitforSent(_u32 timeout ) 
00548     {
00549         fd_set wrset;
00550         FD_ZERO(&wrset);
00551         FD_SET(_socket_fd, &wrset);
00552 
00553         timeval tv;
00554         tv.tv_sec = timeout / 1000;
00555         tv.tv_usec = (timeout % 1000) * 1000;
00556         int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00557 
00558         switch (ans) {
00559             case 1:
00560                 // fired
00561                 return RESULT_OK;
00562             case 0:
00563                 // timeout
00564                 return RESULT_OPERATION_TIMEOUT;
00565             default:
00566                 delay(0); //relax cpu
00567                 return RESULT_OPERATION_FAIL;
00568         }
00569     }
00570 
00571     virtual u_result waitforData(_u32 timeout )
00572     {
00573         fd_set rdset;
00574         FD_ZERO(&rdset);
00575         FD_SET(_socket_fd, &rdset);
00576 
00577         timeval tv;
00578         tv.tv_sec = timeout / 1000;
00579         tv.tv_usec = (timeout % 1000) * 1000;
00580         int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00581 
00582         switch (ans) {
00583             case 1:
00584                 // fired
00585                 return RESULT_OK;
00586             case 0:
00587                 // timeout
00588                 return RESULT_OPERATION_TIMEOUT;
00589             default:
00590                 delay(0); //relax cpu
00591                 return RESULT_OPERATION_FAIL;
00592         }
00593     }
00594 
00595 protected:
00596     int  _socket_fd;
00597 
00598 
00599 };
00600 
00601 
00602 class _single_thread DGramSocketImpl : public DGramSocket
00603 {
00604 public:
00605 
00606     DGramSocketImpl(int fd)
00607         : _socket_fd(fd)
00608     {
00609         assert(fd>=0);
00610         int bool_true = 1;
00611         ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, sizeof(bool_true) );
00612         setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00613     }
00614 
00615     virtual ~DGramSocketImpl() 
00616     {
00617         close(_socket_fd);
00618     }
00619 
00620     virtual void dispose()
00621     {
00622         delete this;
00623     }
00624 
00625 
00626     virtual u_result bind(const SocketAddress & localaddr)
00627     {
00628         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00629         assert(addr);
00630         int ans = ::bind(_socket_fd, addr, sizeof(sockaddr_storage));
00631         if (ans) {
00632             return RESULT_OPERATION_FAIL;
00633         } else {
00634             return RESULT_OK;
00635         }
00636     }
00637 
00638     virtual u_result getLocalAddress(SocketAddress & localaddr)
00639     {
00640         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData()))); //donnot do this at home...
00641         assert(addr);
00642 
00643         size_t actualsize =  sizeof(sockaddr_storage);
00644         int ans = ::getsockname(_socket_fd, addr, (socklen_t*)&actualsize);
00645 
00646         assert(actualsize <= sizeof(sockaddr_storage));
00647         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00648 
00649         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00650     }
00651 
00652     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00653     {
00654         int ans;
00655         timeval tv;
00656         tv.tv_sec = timeout / 1000; 
00657         tv.tv_usec = (timeout % 1000) * 1000; 
00658 
00659         if (msk & SOCKET_DIR_RD) {
00660              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) );
00661              if (ans) return RESULT_OPERATION_FAIL;
00662         }
00663 
00664         if (msk & SOCKET_DIR_WR) {
00665              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) );
00666              if (ans) return RESULT_OPERATION_FAIL;
00667         }
00668 
00669         return RESULT_OK;
00670     }
00671   
00672 
00673     virtual u_result waitforSent(_u32 timeout ) 
00674     {
00675         fd_set wrset;
00676         FD_ZERO(&wrset);
00677         FD_SET(_socket_fd, &wrset);
00678 
00679         timeval tv;
00680         tv.tv_sec = timeout / 1000;
00681         tv.tv_usec = (timeout % 1000) * 1000;
00682         int ans = ::select(_socket_fd+1, NULL, &wrset, NULL, &tv);
00683 
00684         switch (ans) {
00685             case 1:
00686                 // fired
00687                 return RESULT_OK;
00688             case 0:
00689                 // timeout
00690                 return RESULT_OPERATION_TIMEOUT;
00691             default:
00692                 delay(0); //relax cpu
00693                 return RESULT_OPERATION_FAIL;
00694         }
00695     }
00696 
00697     virtual u_result waitforData(_u32 timeout )
00698     {
00699         fd_set rdset;
00700         FD_ZERO(&rdset);
00701         FD_SET(_socket_fd, &rdset);
00702 
00703         timeval tv;
00704         tv.tv_sec = timeout / 1000;
00705         tv.tv_usec = (timeout % 1000) * 1000;
00706         int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00707 
00708         switch (ans) {
00709             case 1:
00710                 // fired
00711                 return RESULT_OK;
00712             case 0:
00713                 // timeout
00714                 return RESULT_OPERATION_TIMEOUT;
00715             default:
00716                 delay(0); //relax cpu
00717                 return RESULT_OPERATION_FAIL;
00718         }
00719     }
00720 
00721     virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
00722     {
00723         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
00724         assert(addr);
00725         size_t ans = ::sendto( _socket_fd, buffer, len, 0, addr, sizeof(sockaddr_storage));
00726         if (ans != (size_t)-1) {
00727             assert(ans == (int)len);
00728             return RESULT_OK;
00729         } else {
00730             switch (errno) {
00731                 case EAGAIN:
00732 #if EWOULDBLOCK!=EAGAIN
00733                 case EWOULDBLOCK:
00734 #endif
00735                     return RESULT_OPERATION_TIMEOUT;
00736 
00737                 case EMSGSIZE:
00738                     return RESULT_INVALID_DATA;
00739                 default:
00740                     return RESULT_OPERATION_FAIL;
00741             }
00742         
00743         }
00744 
00745     }
00746 
00747 
00748     virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00749     {
00750         struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00751         size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00752 
00753         size_t ans = ::recvfrom( _socket_fd, buf, len, 0, addr, (socklen_t*)&source_addr_size);
00754         if (ans == (size_t)-1) {
00755             recv_len = 0;  
00756             switch (errno) {
00757                 case EAGAIN:
00758 #if EWOULDBLOCK!=EAGAIN
00759                 case EWOULDBLOCK:
00760 #endif
00761                     return RESULT_OPERATION_TIMEOUT;
00762                 default:
00763                     return RESULT_OPERATION_FAIL;
00764             }
00765 
00766         } else {
00767             recv_len = ans;
00768             return RESULT_OK;
00769         }
00770 
00771     }
00772 
00773 #if 0
00774     virtual u_result recvFromNoWait(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00775     {
00776         struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00777         size_t source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00778 
00779 
00780         size_t ans = ::recvfrom( _socket_fd, buf, len, MSG_DONTWAIT, addr, &source_addr_size);
00781 
00782         if (ans == (size_t)-1) {
00783             recv_len = 0;  
00784             if (errno == EAGAIN || errno == EWOULDBLOCK) {
00785                 return RESULT_OK; 
00786             } else {
00787                 return RESULT_OPERATION_FAIL;
00788             }
00789 
00790 
00791         } else {
00792             recv_len = ans;
00793             return RESULT_OK;
00794         }
00795 
00796     }
00797 #endif
00798     
00799 protected:
00800     int  _socket_fd;
00801 
00802 };
00803 
00804 
00805 }}}
00806 
00807 
00808 namespace rp { namespace net{ 
00809 
00810 
00811 static inline int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
00812 {
00813     switch (family) {
00814         case SocketBase::SOCKET_FAMILY_INET:
00815             return AF_INET;
00816         case SocketBase::SOCKET_FAMILY_INET6:
00817             return AF_INET6;
00818         case SocketBase::SOCKET_FAMILY_RAW:
00819             assert(!"should not reach here, AF_PACKET is not supported on macOS");
00820             return AF_INET;
00821         default:
00822             assert(!"should not reach here");
00823             return AF_INET; // force treating as IPv4 in release mode
00824     }
00825 
00826 }
00827 
00828 StreamSocket * StreamSocket::CreateSocket(SocketBase::socket_family_t family)
00829 {
00830     if (family == SOCKET_FAMILY_RAW) return NULL;
00831 
00832 
00833     int socket_family = _socketHalFamilyToOSFamily(family);
00834     int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
00835     if (socket_fd == -1) return NULL;
00836 
00837     StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
00838     return newborn;
00839 
00840 }
00841 
00842 
00843 DGramSocket * DGramSocket::CreateSocket(SocketBase::socket_family_t family)
00844 {
00845     int socket_family = _socketHalFamilyToOSFamily(family);
00846 
00847 
00848     int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
00849     if (socket_fd == -1) return NULL;
00850 
00851     DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
00852     return newborn;
00853 
00854 }
00855 
00856 
00857 }}
00858 


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