/* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004 * (C) Copyright Pigeon Point Systems. 2010 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * W. David Ashley * Anton Pak * */ #ifndef STRMSOCK_H_INCLUDED #define STRMSOCK_H_INCLUDED #include #include #ifdef _WIN32 #include #include #else #include #include #include #include #endif /*************************************************************** * IPv4 / IPv6 **************************************************************/ typedef enum { FlagIPv4 = 1, FlagIPv6 = 2 } IPvFlags; /*************************************************************** * Message Header **************************************************************/ const size_t dMhSize = 12; typedef uint8_t MessageHeader[dMhSize]; const size_t dMhOffType = 0; const size_t dMhOffFlags = 1; const size_t dMhOffReserved1 = 2; const size_t dMhOffReserved2 = 3; const size_t dMhOffId = 4; const size_t dMhOffLen = 8; const uint8_t eMhMsg = 1; const uint8_t eMhError = 2; // message flags // bits 0-3 : flags, bit 4-7 : OpenHPI RPC version // if endian bit is set the byte order is Little Endian const uint8_t dMhEndianBit = 1; const uint8_t dMhRpcVersion = 1; const size_t dMaxMessageLength = 0xFFFF; const size_t dMaxPayloadLength = dMaxMessageLength - sizeof(MessageHeader); /*************************************************************** * Base Stream Socket class **************************************************************/ class cStreamSock { public: #ifdef _WIN32 typedef SOCKADDR_STORAGE SockAddrStorageT; typedef int SockAddrLenT; typedef SOCKET SockFdT; static const SockFdT InvalidSockFd = INVALID_SOCKET; #else typedef sockaddr_storage SockAddrStorageT; typedef socklen_t SockAddrLenT; typedef int SockFdT; static const SockFdT InvalidSockFd = -1; #endif explicit cStreamSock( SockFdT sockfd = InvalidSockFd ); virtual ~cStreamSock(); bool Close(); bool GetPeerAddress( SockAddrStorageT& storage ) const; bool ReadMsg( uint8_t& type, uint32_t& id, void * payload, uint32_t& payload_len, int& payload_byte_order ); bool WriteMsg( uint8_t type, uint32_t id, const void * payload, uint32_t payload_len ); enum eWaitCc { eWaitSuccess, eWaitTimeout, eWaitError, }; eWaitCc Wait(); protected: SockFdT SockFd() const { return m_sockfd; } bool CreateAttempt( const struct addrinfo * ainfo, bool last_attempt ); private: cStreamSock( const cStreamSock& ); cStreamSock& operator =( const cStreamSock& ); private: SockFdT m_sockfd; }; /*************************************************************** * Client Stream Socket class **************************************************************/ class cClientStreamSock : public cStreamSock { public: explicit cClientStreamSock(); ~cClientStreamSock(); bool Create( const char * host, uint16_t port ); /*********************** * TCP Keep-Alive * * keepalive_time - interval(sec) between the last data packet sent and * the first keepalive probe * keepalive_intvl - interval(sec) between subsequential keepalive probes * keepalive_probes - number of unacknowledged probes to send before * considering the connection dead **********************/ bool EnableKeepAliveProbes( int keepalive_time, int keepalive_intvl, int keepalive_probes ); private: cClientStreamSock( const cClientStreamSock& ); cClientStreamSock& operator =( const cClientStreamSock& ); bool CreateAttempt( const struct addrinfo * ainfo, bool last_attempt ); }; /*************************************************************** * Server Stream Socket class **************************************************************/ class cServerStreamSock : public cStreamSock { public: explicit cServerStreamSock(); ~cServerStreamSock(); bool Create( int ipvflags, const char * bindaddr, uint16_t port ); cStreamSock * Accept(); private: cServerStreamSock( const cServerStreamSock& ); cServerStreamSock& operator =( const cServerStreamSock& ); bool CreateAttempt( const struct addrinfo * ainfo, bool last_attempt ); }; #endif // STRMSOCK_H_INCLUDED__