Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Wireless.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_Wireless_h_
00003 #define INCLUDED_Wireless_h_
00004 
00005 #ifdef PLATFORM_APERIOS
00006 #  include <OPENR/OObject.h>
00007 #  include <OPENR/OSubject.h>
00008 #  include <OPENR/OObserver.h>
00009 #  include <ant.h>
00010 #else
00011 #  include "IPC/Thread.h"
00012 #  include "Shared/Resource.h"
00013 typedef unsigned long uint32;
00014 #endif
00015 #include "Socket.h"
00016 #include "DummySocket.h"
00017 #include <list>
00018 
00019 using namespace SocketNS;
00020 using namespace __gnu_cxx;
00021 
00022 //! Tekkotsu wireless class
00023 /*!
00024  * For more information on using wireless, please read the following tutorials:
00025  * - <a href="../TekkotsuMon.html">TekkotsuMon</a>
00026  * - <a href="../Wireless.html">TCP/IP</a>
00027  *
00028  * The networking interface needs more documentation.  It also needs a
00029  * cleanup.  In the mean time, take a look at the TekkotsuMon objects
00030  * in <i>Tekkotsu</i><tt>/Behaviors/Mon</tt>.  They all listen for new
00031  * connections.  Unfortunately, at the momement there are no examples
00032  * of outgoing connections, but it should give you a pretty good idea
00033  * how to start moving.
00034  */
00035 class Wireless {
00036 public:
00037   //! Maximum number of sockets which can be created
00038   static const int WIRELESS_MAX_SOCKETS=100;
00039   
00040   //! Default number of bytes to use for receive buffers (overridden by value passed to socket())
00041   static const int WIRELESS_DEF_RECV_SIZE=1024;
00042   
00043   //! Default number of bytes to use for send buffers (overridden by value passed to socket())
00044   static const int WIRELESS_DEF_SEND_SIZE=1024;
00045   
00046   //! constructor - only one wireless object is required per Aperios process. 
00047   /*! MMCombo already creates one. The (global) instance is called wireless,
00048    * and you can access it by including Wireless/Wireless.h (this file) in
00049    * your code
00050    */
00051   Wireless();
00052   ~Wireless(); //!< destructor
00053   
00054   //@{
00055   //! Creates a new socket
00056   /*! @return pointer to Socket object created
00057    * @param ttype selects between TCP and UDP
00058    * @see WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE */
00059   Socket* socket(TransportType_t ttype);
00060   /*!@param ttype selects between TCP and UDP
00061    * @param recvsize size of input buffer
00062    * @param sendsize size of output buffer
00063    */
00064   Socket* socket(TransportType_t ttype, int recvsize, int sendsize);
00065   //@}
00066 
00067   //! The socket waits for incoming connections.
00068   /*! That is, it acts like a server. If a connection is established and
00069    * later broken, it resumes waiting for new connections if the
00070    * socket's daemon flag is set.
00071    */
00072   int listen(int sock, int port);
00073 
00074   //! The socket tries to connect to a specific
00075   int connect(int sock, const char* ipaddr, int port);
00076   //! sets receiver callback for a socket
00077   void setReceiver(int sock, int (*rcvcbckfn) (char*, int) );
00078   //! sets the socket to be a daemon (recycles on close)
00079   void setDaemon(int sock, bool val=true) { sockets[sock]->daemon=val; }
00080   //! sets the socket to be a daemon (recycles on close)
00081   bool getDaemon(int sock) { return sockets[sock]->daemon; }
00082   //! closes and destroys non server, daemon sockets
00083   void close(int sock);
00084 
00085   //@{
00086   //! utility function that you can use if you're curious about the state of the socket.
00087   /*! You shouldn't need to use it, since asking sockets for write
00088    * and read buffers does the necessary sanity checks
00089    */
00090   bool isConnected(int sock) {
00091     return sockets[sock]==NULL ? false : sockets[sock]->state==CONNECTION_CONNECTED;
00092   }
00093   bool isError(int sock) {
00094     return sockets[sock]==NULL ? false : sockets[sock]->state==CONNECTION_ERROR;
00095   }
00096 
00097   bool isReady(int sock) { return !sockets[sock]->tx; }
00098   bool hasData(int sock) { return !sockets[sock]->rx; }
00099   //@}
00100 
00101   //@{
00102   //! helper function for the function with the same name that takes a socket descriptor (int)
00103   void setReceiver(Socket &sobj, int (*rcvcbckfn) (char*, int) )
00104     { setReceiver(sobj.sock, rcvcbckfn); }
00105   void setReceiver(Socket *sobj, int (*rcvcbckfn) (char*, int) )
00106     { setReceiver(sobj->sock, rcvcbckfn); }
00107   void setDaemon(Socket &sobj, bool val=true) { setDaemon(sobj.sock, val); }
00108   void setDaemon(Socket *sobj, bool val=true) { setDaemon(sobj->sock, val); }
00109   bool getDaemon(Socket &sobj) { return getDaemon(sobj.sock); }
00110   bool getDaemon(Socket *sobj) { return getDaemon(sobj->sock); }
00111   int listen(Socket &sobj, int port) { return listen(sobj.sock, port); } 
00112   int listen(Socket *sobj, int port) { return listen(sobj->sock, port); } 
00113   int connect(Socket &sobj, const char* ipaddr, int port)
00114     { return connect (sobj.sock, ipaddr, port); }
00115   int connect(Socket *sobj, const char* ipaddr, int port)
00116     { return connect (sobj->sock, ipaddr, port); }
00117   void close(Socket &sobj) { close(sobj.sock); }
00118   void close(Socket *sobj) { close(sobj->sock); }
00119   unsigned int getNumInterfaces() { return 1; }
00120   uint32 getIPAddress(unsigned int idx=0);
00121   //@}
00122 
00123   //@{
00124   //! function for internal and Socket use. You should not call this
00125   void receive(int sock, int (*rcvcbckfn) (char*, int) );
00126   void receive(int sock);
00127   //@}
00128 
00129   //@{
00130   //! function called by the Socket objects to actually write
00131   //! data to the network. You should not call this.
00132   void send(int sock);
00133   void blockingSend(int sock);
00134   //@}
00135   
00136 #ifdef PLATFORM_APERIOS
00137   //@{
00138   //! callback function for communicating
00139   //! with Aperios Networking Toolkit. You should not call this.
00140   void ListenCont (void* msg);
00141   void BindCont   (void* msg);
00142   void ConnectCont(void* msg);
00143   void SendCont   (void* msg);
00144   void ReceiveCont(void* msg);
00145   void CloseCont  (void* msg);
00146   //@}
00147 
00148 #else
00149   void pollSetup(); //!< on non-aperios, set up structures to be checked in pollTest()
00150   bool pollTest(struct timeval* tv); //!< on non-aperios, check to see any network communication has occurred
00151   void pollProcess(); //!< on non-aperios, process callbacks and state changes as signaled in pollTest()
00152   void wakeup(Socket * del=NULL); //!< writes @a del on #interruptCtl, breaking out of a pending pollTest() and thus giving an opportunity to change the contents of the FD sets being used;
00153 
00154   void setCallbackLock(Resource& l); //!< sets #callbackLock
00155   void clearCallbackLock(); //!< resets #callbackLock to a self-defined lock, which you can request from getCallbackLock() (there's always a callbackLock, the only question is it internally or externally instantiated)
00156   Resource& getCallbackLock() const { static ThreadNS::Lock cl; return callbackLock==NULL ? cl : *callbackLock; } //!< returns #callbackLock
00157 #endif
00158 
00159 protected:
00160   friend class Socket; //so socket can lock as well
00161   static const int MAXCONNECTIONS = 5; //!< the maximum number of connections which can be queued when listening
00162 
00163   //@{
00164   //!private ALOKL_TODO
00165 #ifdef PLATFORM_APERIOS
00166   antStackRef ipstackRef;
00167   OID myOID;
00168 #else
00169   static Resource& getLock(); //!< returns the lock to use during @e all wireless operations (not just callbacks, this is more general)
00170   Resource* callbackLock; //!< this lock will be aquired during any callbacks which might occur during pollProcess()
00171   int interruptChk; //!< a socket, connected to #interruptCtl, which allows pollTest() to be interrupted if new sockets need to be polled
00172   int interruptCtl; //!< a socket, connected to #interruptChk, which allows pollTest() to be interrupted if new sockets need to be polled
00173   fd_set rfds; //!< a set of file descriptors which should be polled for readable data; set up by pollSetup(), watched (blocking) by pollTest(), and processed by pollProcess()
00174   fd_set wfds; //!< a set of file descriptors which should be polled for write-complete; set up by pollSetup(), watched (blocking) by pollTest(), and processed by pollProcess()
00175   fd_set efds; //!< a set of file descriptors which should be polled for errors; set up by pollSetup(), watched (blocking) by pollTest(), and processed by pollProcess()
00176   int fdsMax; //!< maximum file descriptor value in the #rfds, #wfds, #efds fd_set's
00177 #endif
00178   Socket* sockets[WIRELESS_MAX_SOCKETS];
00179   std::list<int> freeSockets;
00180   std::list<int> usedSockets;
00181   //@}
00182 
00183 private:
00184   Wireless(const Wireless&); //!< don't call
00185   Wireless& operator= (const Wireless&); //!< don't call
00186 };
00187 
00188 //! the global wireless object - you'll want to make your function calls on this
00189 extern Wireless* wireless;
00190 
00191 /*! @file
00192  * @brief Interacts with the system to provide networking services
00193  * @author alokl (Creator)
00194  * 
00195  * @verbinclude CMPack_license.txt
00196  *
00197  * $Author: ejt $
00198  * $Name: tekkotsu-3_0 $
00199  * $Revision: 1.27 $
00200  * $State: Exp $
00201  * $Date: 2006/09/22 16:59:26 $
00202  */
00203 
00204 #endif // Wireless_h_DEFINED

Tekkotsu v3.0
Generated Wed Oct 4 00:03:47 2006 by Doxygen 1.4.7