Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Socket.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef Socket_h_DEFINED
00003 #define Socket_h_DEFINED
00004 
00005 #ifdef PLATFORM_APERIOS
00006 #  include <ant.h>
00007 #  include <Types.h>
00008 #else
00009 #  include <sys/socket.h>
00010 #endif
00011 #include <stdarg.h>
00012 #include <stdlib.h>
00013 #include <string>
00014 
00015 //! holds socket enumerations and constants
00016 namespace SocketNS {
00017   
00018 #ifdef PLATFORM_APERIOS
00019   const int _SYS_SOCK_STREAM=1; //!< aperios doesn't provide SOCK_STREAM, so we will initialize them to these values
00020   const int _SYS_SOCK_DGRAM=2;  //!< aperios doesn't provide SOCK_DGRAM, so we will initialize them to these values
00021 #else
00022   //this is why you shouldn't use #define to declare constant values... grrr
00023   const int _SYS_SOCK_STREAM=SOCK_STREAM;
00024   const int _SYS_SOCK_DGRAM=SOCK_DGRAM;
00025 #  ifdef SOCK_STREAM
00026 #    undef SOCK_STREAM
00027 #  endif
00028 #  ifdef SOCK_DGRAM
00029 #    undef SOCK_DGRAM
00030 #  endif
00031 #endif
00032   //! Specifies transport type. TCP is usually a good idea
00033   enum TransportType_t {
00034     SOCK_STREAM=_SYS_SOCK_STREAM, //!< TCP: guaranteed delivery, higher overhead
00035     SOCK_DGRAM=_SYS_SOCK_DGRAM     //!< UDP: no guarantees, low overhead
00036   };
00037 
00038   //! Internal TCP/UDP Connection State
00039   enum ConnectionState {
00040     CONNECTION_CLOSED,
00041     CONNECTION_CONNECTING,
00042     CONNECTION_CONNECTED,
00043     CONNECTION_LISTENING,
00044     CONNECTION_CLOSING,
00045     CONNECTION_ERROR
00046   };
00047 
00048   //! Chooses between blocking and non-blocking Wireless Input, Output. Blocking wireless output from the main process will affect the performance of the Aibo, and should only be used for debugging purposes
00049   enum FlushType_t {
00050     FLUSH_NONBLOCKING=0, //!< Writes and Reads return immediately, and are processed by another process, so Main can continue to run. Non-blocking reads require specifying a callback function to handle data received
00051     FLUSH_BLOCKING       //!< Blocking writes are a good idea for debugging - a blocking write will be transmitted before execution continues to the next statement. Blocking reads should be avoided, since they'll cause a significant slow down in the main process
00052   };
00053 
00054 };
00055 
00056 using namespace SocketNS;
00057 
00058 #ifndef PLATFORM_APERIOS
00059   typedef unsigned char byte;
00060 #endif
00061 
00062 //! Tekkotsu wireless Socket class
00063 /*! 
00064  * For more information on using wireless, please read the following tutorials:
00065  * - <a href="../AiboMon.html">TekkotsuMon</a>
00066  * - <a href="../Wireless.html">TCP/IP</a>
00067  * - <a href="../RemoteProcess.html">Remote Processing OPENR</a>
00068  * Tekkotsu Wireless and Remote Processing OPENR provide different
00069  * interfaces to comparable wireless functionality.
00070  *
00071  * The networking interface needs more documentation.  It also needs a
00072  * cleanup.  In the mean time, take a look at the TekkotsuMon objects
00073  * in <i>Tekkotsu</i><tt>/Behaviors/Mon</tt>.  They all listen for new
00074  * connections.  Unfortunately, at the momement there are no examples
00075  * of outgoing connections, but it should give you a pretty good idea
00076  * how to start moving.
00077  */
00078 
00079 class Socket {
00080   friend class Wireless;
00081 
00082 public:
00083   int sock; //!< unique non-negative integer representing socket. Serves as index into socket Objects array
00084 
00085 public:
00086   //! constructor
00087   explicit Socket(int sockn)
00088     : sock(sockn), trType(), flType(FLUSH_NONBLOCKING), verbosity(0), 
00089       endpoint(), state(CONNECTION_CLOSED), sendBufSize(), recvBufSize(),
00090       sendSize(0), sentSize(0), recvSize(0), writeSize(0), readSize(0),
00091       tx(false), rx(false), sendBuffer(), sendData(NULL), writeData(NULL), 
00092       recvBuffer(), recvData(NULL), readData(NULL), server_port(0), 
00093       rcvcbckfn(NULL), peer_addr(-1), peer_port(-1), textForward(false), textForwardBuf(NULL),
00094       forwardSock(NULL), daemon(false)
00095   {
00096 #ifndef PLATFORM_APERIOS
00097     endpoint=-1;
00098 #endif
00099   }
00100   virtual ~Socket(); //!< destructor
00101 
00102   //! use getWriteBuffer to get a memory address to write bytes to, for
00103   //! subsequent writing to a connection.
00104   /*!
00105    * The getWriteBuffer-write(int) combo eliminates one buffer copy. You
00106    * don't need to use getWriteBuffer with write(byte*, int)
00107    * @return pointer to the current position in the current write buffer for this socket or NULL on error
00108    * @param bytesreq maximum number of bytes the caller intends to set before the write method is called */
00109   byte* getWriteBuffer(int bytesreq);
00110 
00111   //! writes the specified number of bytes starting at the pointer returned.
00112   /*!
00113    * in a (prior) call to getWriteBufer
00114    * @param size number of bytes to be sent from the current write buffer
00115    */
00116   void write(int size);
00117 
00118   //! Blocking read. NOT IMPLEMENTED
00119   /*!
00120    * Tries to read upto receive buffer size worth of data from this socket.
00121    *
00122    * Blocking read is currently broken - it will be fixed in the next release
00123    * @return number of bytes read or -1 on error
00124    */
00125   int read();
00126 
00127   //! getReadBuffer is used with blocking read's NOT IMPLEMENTED
00128   /*!
00129    * The read(void) and getReadBuffer combo eliminates one buffer copy. You
00130    * don't need to use getReadBuffer with read(byte*, int)
00131    *
00132    * Blocking read is currently broken - it will be fixed in the next release
00133    * @return pointer to the buffer the previous call to blocking read wrote into or NULL if no data was read
00134    */
00135   byte* getReadBuffer();
00136 
00137   //! initialize socket member variables. This is different from the constructor since sockets are reused
00138   void init(); 
00139 
00140   //! Chooses between blocking and non-blocking input, output.
00141   /*! This function
00142    * can only be called when a socket is disconnected, since it is a bad
00143    * idea to mix blocking and non-blocking input, output.
00144    * The default for a socket is non-blocking
00145    * @return 0 on success
00146    */
00147   int setFlushType(FlushType_t fType);
00148   
00149   //! can choose between different transports; will reset the socket
00150   int setTransport(TransportType_t tr);
00151 
00152   //!causes this socket to forward output to stdout if it is not connected, call setForward(NULL) to unset
00153   void setTextForward() { textForward=true; forwardSock=NULL; }
00154 
00155   //!causes this socket to forward output to @a sock if it is not connected, pass NULL to unset
00156   void setForward(Socket * forsock) { forwardSock=forsock; textForward=false; }
00157 
00158   //! Picks a level of verbosity for filtering pprintf commands.
00159   /*! The higher the
00160    * verbosity, the more the number of messages printed. This is useful
00161    * for filtering out non-important messages with very little processor
00162    * cost. Default is 0.
00163    * @param verbose the higher the value of verbose, the more the output
00164    */
00165   void setVerbosity(int verbose) { verbosity=verbose; }
00166 
00167   //! Standard write - writes specified amount of data from a buffer to a
00168   //! connection
00169   /*! You might want to consider the getWriteBuffer-write(int) combo if you
00170    * call this often
00171    * @param buf buffer to write from
00172    * @param size number of bytes to write
00173    * @return the number of bytes actually written or -1 on error
00174    */
00175   int write(const byte *buf, int size);
00176 
00177   //! Blocking read (NOT IMPLEMENTED)
00178   /*! You might want to consider the read(void) and getReadBuffer combo if you
00179    * call this often
00180    *
00181    * Blocking read is currently broken - it will be fixed in the next release
00182    * @param buf buffer to write from
00183    * @param size number of bytes to write
00184    * @return number of bytes actually read
00185    */
00186   int read(byte *buf, int size);
00187 
00188   //! It's standard stuff. man 3 printf on most systems should give you more
00189   //! information
00190   int printf(const char *fmt, ...) __attribute__((format(printf,2,3)));
00191 
00192   //! It's standard stuff. man 3 printf on most systems should give you more
00193   //! information
00194   int vprintf(const char *fmt, va_list al) __attribute__ ((format (printf, 2, 0)));
00195 
00196   //! Similar to printf, except it takes an extra first argument.
00197   /*! If vlevel is than or equal to the current #verbosity level,
00198    *  the string will be printed else it will be ignored.
00199    *  @param vlevel if (vlevel<=verbosity) print, else ignore
00200    *  @param fmt same as the standard printf's format string
00201    */
00202   int pprintf(int vlevel, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
00203   
00204   //! Initiate blocking or nonblocking write transfer depending on the type
00205   //! of socket.
00206   /*! All write commands on the socket will implicity call this. You
00207    * don't need to call it, unless you're implementing your own write
00208    */
00209   void flush();
00210   
00211   //! returns #daemon
00212   bool getDaemon() const { return daemon; }
00213   
00214   int getPeerAddress() const { return peer_addr; } //!< returns the address of the remote host in local host byte order
00215   std::string getPeerAddressAsString() const; //!< returns the address of the remote host as a human-readable string
00216   int getPeerPort() const { return peer_port; } //!< returns the port number that the remote host's socket is on
00217 
00218 protected:
00219   TransportType_t trType; //!< stores choice between transports (UDP or TCP (aka Datagram or Stream))
00220   FlushType_t flType; //!< blocking or non-blocking flushes... note that blocking flushes only block on the handoff to the system, not actual transmission (at least under aperios)
00221 
00222   int verbosity; //!< can be used to filter calls to pprintf
00223 
00224 #ifdef PLATFORM_APERIOS
00225   typedef antSharedBuffer buf_t; //!< the Aibo Networking Toolkit buffer data structure
00226   typedef antModuleRef endp_t; //!< the Aibo Networking Toolkit endpoint data structure
00227 #else
00228   typedef char* buf_t; //!< a general buffer
00229   typedef int endp_t; //!< a unix socket descriptor
00230 #endif
00231 
00232   endp_t endpoint; //!< holds the endpoint data structure for the host OS
00233   ConnectionState state; //!< an enum representing the current state of the socket
00234 
00235   int sendBufSize; //!< the size of the buffer for #sendData and #writeData
00236   int recvBufSize; //!< the size of the buffer for #readData and #recvData
00237   int sendSize; //!< the size of #sendData (total amount of data from last flush)
00238   int sentSize; //!< the sent portion of #sendData (amount of data which has been sent to system so far)
00239   int recvSize; //!< the size of #recvData (total amount of data returned by system)
00240   int writeSize; //!< the size of #writeData (amount of data so far ready to be flushed)
00241   int readSize; //!< the size of #readData (not used)
00242   bool tx; //!< a flag set when #sendData is in the process of being sent to the system
00243   bool rx; //!< not used, see #readData
00244 
00245   buf_t sendBuffer; //!< under aperios, a pointer to a shared region with the ip stack; under other OS, a pointer to a normal char * buffer
00246   byte *sendData; //!< a region within #sendBuffer, holding data in the process of being sent
00247   byte *writeData; //!< a region within #sendBuffer, holds data still being filled in by user code, not yet flushed
00248 
00249   buf_t recvBuffer; //!< under aperios, a pointer to a shared region with the ip stack; under other OS, a pointer to a normal char * buffer
00250   byte *recvData; //!< a region within #recvBuffer, holding data either just filled in by ip stack (during call to #rcvcbckfn), or in the process of being filled in (any other time)
00251   byte *readData; //!< not used (available for double buffering, but not implemented)
00252   
00253   int server_port; //!< if the socket is a server socket, this is the port it is listening on
00254   int (*rcvcbckfn) (char*, int); //!< pointer to callback function, called after #recvData has been filled in
00255   
00256   int peer_addr; //!< inet address of peer (if connected) or last message sender (if udp and bound); -1 otherwise (in host byte-order, not network byte-order!)
00257   int peer_port; //!< port of peer (if connected) or last message sender (if udp and bound); -1 otherwise
00258 
00259   bool textForward; //!< if true, when data is sent to the socket and the socket is not current connected, the data will be sent to stdout (overridden by #forwardSock)
00260   char* textForwardBuf; //!< temporary buffer allocated in getWriteBuffer() and freed in write(), if the output is destined for stdout (#textForward)
00261   Socket * forwardSock; //!< if non-NULL, output will be sent to this socket if the current socket is not otherwise connected (overrides #textForward)
00262 
00263   bool daemon; //!< if true, the socket will automatically be reopened after any closure (manual or otherwise)
00264  
00265 protected:
00266   Socket(const Socket&); //!< copy constructor, don't call
00267   Socket& operator= (const Socket&); //!< assignment operator, don't call
00268 };
00269 
00270 extern Socket* sout;  //!< the standard tekkotsu in/out console (default port 10001)
00271 extern Socket* serr;  //!< the standard tekkotsu error output (default port 10002)
00272 
00273 /*! @file
00274  * @brief Defines Tekkotsu wireless Socket class, also sout and serr
00275  * @author alokl (Creator)
00276  * 
00277  * $Author: ejt $
00278  * $Name: tekkotsu-2_4_1 $
00279  * $Revision: 1.23 $
00280  * $State: Exp $
00281  * $Date: 2005/08/07 04:11:04 $
00282  */
00283 
00284 #endif

Tekkotsu v2.4.1
Generated Tue Aug 16 16:32:48 2005 by Doxygen 1.4.4