Homepage Demos Overview Downloads Tutorials Reference
Credits

Wireless.cc

Go to the documentation of this file.
00001 #include <OPENR/OSyslog.h>
00002 #include <OPENR/OPENRAPI.h>
00003 #include <ant.h>
00004 #include <EndpointTypes.h>
00005 #include <TCPEndpointMsg.h>
00006 #include <UDPEndpointMsg.h>
00007 #include <cstring>
00008 #include "Wireless.h"
00009 #include "Socket.h"
00010 #include "MMCombo/entry.h"
00011 
00012 using namespace SocketNS;
00013 
00014 Wireless *wireless=NULL;
00015 
00016 Wireless::Wireless ()
00017   : ipstackRef(), myOID(), freeSockets()
00018 {
00019   ipstackRef = antStackRef("IPStack");
00020   WhoAmI(&myOID);
00021 
00022   sockets[0]=new DummySocket(0);
00023   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00024     sockets[sock]=NULL;
00025     freeSockets.push_back(sock);
00026   }
00027 }    
00028 
00029 Wireless::~Wireless ()
00030 {
00031   // TODO
00032 }
00033 
00034 Socket* Wireless::socket(TransportType_t ttype)
00035 {
00036   return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00037 }
00038 
00039 Socket* Wireless::socket(TransportType_t ttype, int recvsize, int sendsize)
00040 {
00041   if (freeSockets.empty()
00042       || (recvsize + sendsize) <= 256) return sockets[0];
00043   int sock_num=freeSockets.front();
00044   freeSockets.pop_front();
00045 
00046   sockets[sock_num]=new Socket(sock_num);
00047   sockets[sock_num]->trType=ttype;
00048   sockets[sock_num]->sendBufSize=sendsize;
00049   sockets[sock_num]->recvBufSize=recvsize;
00050 
00051   // setup send buffer
00052   antEnvCreateSharedBufferMsg sendBufferMsg(sendsize*2);
00053   sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00054   if (sendBufferMsg.error != ANT_SUCCESS) return sockets[0];
00055 
00056   sockets[sock_num]->sendBuffer = sendBufferMsg.buffer;
00057   sockets[sock_num]->sendBuffer.Map();
00058   sockets[sock_num]->sendData = ( byte * ) ( sockets[sock_num]->sendBuffer.GetAddress() );
00059 
00060   // setup receive buffer
00061   antEnvCreateSharedBufferMsg recvBufferMsg(recvsize*2);
00062   recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00063   if (recvBufferMsg.error != ANT_SUCCESS) return sockets[0];
00064 
00065   sockets[sock_num]->recvBuffer = recvBufferMsg.buffer;
00066   sockets[sock_num]->recvBuffer.Map();
00067   sockets[sock_num]->recvData = ( byte * ) ( sockets[sock_num]->recvBuffer.GetAddress() );
00068 
00069   sockets[sock_num]->readData = sockets[sock_num]->recvData + recvsize;
00070   sockets[sock_num]->writeData = sockets[sock_num]->sendData + sendsize;
00071 
00072   return sockets[sock_num]; 
00073 }
00074 
00075 int Wireless::listen(int sock, int port)
00076 {
00077   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00078        || sockets[sock]->state != CONNECTION_CLOSED )return -1;
00079 
00080   sockets[sock]->server_port = port;
00081   sockets[sock]->init();
00082 
00083   if (sockets[sock]->trType==SOCK_STREAM) {
00084     // create endpoint
00085     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00086     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00087     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00088     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00089 
00090     // listen
00091     TCPEndpointListenMsg listenMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00092     listenMsg.continuation = ( void * ) sock;
00093 
00094     listenMsg.Send( ipstackRef, myOID, Extra_Entry[entryListenCont], sizeof( listenMsg ) );
00095 
00096     sockets[sock]->state = CONNECTION_LISTENING;
00097     return 0;
00098   } else if (sockets[sock]->trType==SOCK_DGRAM) {
00099     // create endpoint
00100     antEnvCreateEndpointMsg udpCreateMsg( EndpointType_UDP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00101     udpCreateMsg.Call( ipstackRef, sizeof( udpCreateMsg ) );
00102     if ( udpCreateMsg.error != ANT_SUCCESS ) return -1;
00103 
00104     // bind socket
00105     sockets[sock]->endpoint = udpCreateMsg.moduleRef;
00106     UDPEndpointBindMsg bindMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00107     bindMsg.Call( ipstackRef, sizeof( bindMsg ) );
00108     bindMsg.continuation = ( void * ) sock;
00109 
00110     sockets[sock]->state = CONNECTION_CONNECTING;
00111 
00112     receive( sock );
00113 
00114     return 0;
00115 
00116   }
00117 
00118   else
00119     return -1;
00120 }
00121 
00122 /** Tell the ipstack we want to recieve messages with this function. */
00123 
00124 int Wireless::connect( int sock, const char * ipaddr, int port )
00125 {
00126   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00127        || ( sockets[sock]->trType == SOCK_STREAM && sockets[sock]->state != CONNECTION_CLOSED ) ) return -1;
00128 
00129   sockets[sock]->init();
00130   if (sockets[sock]->trType==SOCK_STREAM) {
00131     // create endpoint
00132     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00133     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00134     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00135     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00136 
00137     // connect
00138     TCPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, IP_ADDR_ANY, IP_PORT_ANY, ipaddr, port );
00139     connectMsg.continuation = ( void * ) sock;
00140 
00141     connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00142 
00143     sockets[sock]->state = CONNECTION_CONNECTING;
00144     return 0;
00145   }
00146 
00147   else if ( sockets[sock]->trType == SOCK_DGRAM )
00148     {
00149       // connect
00150       UDPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, ipaddr, port );
00151 
00152       connectMsg.continuation = ( void * ) sock;
00153 
00154       connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00155 
00156       sockets[sock]->state = CONNECTION_CONNECTED;
00157       //std::cout << "Sock " << sock << " connected via UDP to IP " << ipaddr << " port " << port << std::flush << std::endl;
00158 
00159       return 0;
00160     }
00161 
00162   else
00163     {
00164       return -1;
00165     }
00166 }
00167 
00168 void
00169 Wireless::ListenCont(void* msg)
00170 {
00171   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00172   int sock = ( int )( Msg->continuation );
00173 
00174   if ( sockets[sock]->trType == SOCK_STREAM )
00175     {
00176       TCPEndpointListenMsg * listenMsg = ( TCPEndpointListenMsg * ) msg;
00177 
00178       if ( listenMsg->error != TCP_SUCCESS )
00179         {
00180           sockets[sock]->state = CONNECTION_ERROR;
00181 
00182           // no use recycling since its a resource issue
00183           return;
00184         }
00185 
00186       sockets[sock]->state = CONNECTION_CONNECTED;
00187       receive( sock );
00188     }
00189 }
00190 
00191 void
00192 Wireless::ConnectCont(void *msg)
00193 {
00194   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00195   int sock = ( int )( Msg->continuation );
00196 
00197   if ( sockets[sock]->trType == SOCK_STREAM )
00198     {
00199       TCPEndpointConnectMsg * connectMsg = ( TCPEndpointConnectMsg * ) msg;
00200       if ( connectMsg->error != TCP_SUCCESS )
00201         {
00202           sockets[sock]->state = CONNECTION_ERROR;
00203           return;
00204         }
00205 
00206       sockets[sock]->state = CONNECTION_CONNECTED;
00207       receive( sock );
00208     }
00209 }
00210 
00211 void
00212 Wireless::BindCont(void *msg)
00213 {
00214   UDPEndpointBindMsg* bindMsg = (UDPEndpointBindMsg*)msg;
00215   int sock = (int)bindMsg->continuation;
00216 
00217   if (bindMsg->error != UDP_SUCCESS) {
00218     sockets[sock]->state = CONNECTION_ERROR;
00219     return;
00220   }
00221 
00222   sockets[sock]->state = CONNECTION_CONNECTED;
00223 }
00224 
00225 void
00226 Wireless::send(int sock)
00227 {
00228   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00229        || sockets[sock]->sendSize <= 0 ) return;
00230 
00231   if ( sockets[sock]->trType == SOCK_STREAM )
00232     {
00233       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00234       sendMsg.continuation = ( void * ) sock;
00235 
00236       sockets[sock]->tx = true;
00237       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( TCPEndpointSendMsg ) );
00238       sockets[sock]->sendSize = 0;
00239     }
00240 
00241   else if ( sockets[sock]->trType == SOCK_DGRAM )
00242     {
00243       UDPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00244 
00245       // this field is just hijacked to id the socket # this message is being sent across
00246       sendMsg.continuation = ( void * ) sock;
00247 
00248       sockets[sock]->tx = true;
00249       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( UDPEndpointSendMsg ) );
00250       sockets[sock]->sendSize = 0;
00251     }
00252 }
00253 
00254 void
00255 Wireless::SendCont(void* msg)
00256 {
00257   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00258   int sock = ( int )( Msg->continuation );
00259 
00260   if ( sockets[sock]->trType == SOCK_STREAM )
00261     {
00262       TCPEndpointSendMsg * sendMsg = ( TCPEndpointSendMsg * ) msg;
00263       sockets[sock]->tx = false;
00264       if ( sendMsg->error != TCP_SUCCESS )
00265         {
00266           sockets[sock]->state = CONNECTION_ERROR;
00267           close( sock );
00268           return;
00269         }
00270     }
00271 
00272   else if ( sockets[sock]->trType == SOCK_DGRAM )
00273     {
00274       UDPEndpointSendMsg * sendMsg = ( UDPEndpointSendMsg * ) msg;
00275       sockets[sock]->tx = false;
00276       if ( sendMsg->error != UDP_SUCCESS )
00277         {
00278           sockets[sock]->state = CONNECTION_ERROR;
00279           close( sock );
00280           return;
00281         }
00282     }
00283 
00284   sockets[sock]->flush();
00285 }
00286 
00287 /*! @bug This doesn't actually seem to block until the message is
00288 * fully sent... a crash immediately after this will still cause a
00289 * line or two to be dropped.  This is still less dropped than
00290 * regular send, but doesn't do much good for debugging until we fix
00291 * this. (if we can...) */
00292 void
00293 Wireless::blockingSend(int sock)
00294 {
00295   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00296        || sockets[sock]->sendSize <= 0 ) return;
00297 
00298   if ( sockets[sock]->trType == SOCK_STREAM )
00299     {
00300       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00301       sendMsg.continuation = ( void * ) sock;
00302 
00303       sockets[sock]->tx=true;
00304       sockets[sock]->sendSize = 0;
00305       sendMsg.Call( ipstackRef, sizeof( TCPEndpointSendMsg ) );
00306       sockets[sock]->tx = false;
00307     }
00308 
00309   // no double buffering
00310 }
00311 
00312 void
00313 Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) )
00314 {
00315   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL) return;
00316 
00317   sockets[sock]->rcvcbckfn=rcvcbckfn;
00318 }
00319 
00320 void
00321 Wireless::receive(int sock)
00322 {
00323   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00324        || ( sockets[sock]->trType == SOCK_STREAM && sockets[sock]->state != CONNECTION_CONNECTED ) )
00325     return;
00326 
00327   if ( sockets[sock]->trType == SOCK_STREAM )
00328     {
00329       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00330       receiveMsg.continuation = ( void * ) sock;
00331       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00332     }
00333 
00334   else if ( sockets[sock]->trType == SOCK_DGRAM )
00335     {
00336       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00337       receiveMsg.continuation = ( void * ) sock;
00338       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00339     }
00340 
00341   sockets[sock]->rx = true;
00342 }
00343 
00344 void
00345 Wireless::receive(int sock, int (*rcvcbckfn) (char*, int) )
00346 {
00347   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00348       || sockets[sock]->state != CONNECTION_CONNECTED) return;
00349 
00350   sockets[sock]->rcvcbckfn = rcvcbckfn;
00351 
00352   if ( sockets[sock]->trType == SOCK_STREAM )
00353     {
00354       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00355       receiveMsg.continuation = ( void * ) sock;
00356       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00357     }
00358 
00359   else if ( sockets[sock]->trType == SOCK_DGRAM )
00360     {
00361       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00362       receiveMsg.continuation = ( void * ) sock;
00363       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00364     }
00365 
00366   sockets[sock]->rx = true;
00367 }
00368 
00369 void
00370 Wireless::ReceiveCont(void* msg)
00371 {
00372   // get the socket index before casting the message into UDP or TCP form
00373   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00374   int sock = ( int )( Msg->continuation );
00375 
00376   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00377        || ( sockets[sock]->state != CONNECTION_CONNECTED && sockets[sock]->state != CONNECTION_CONNECTING ) )
00378     return;
00379 
00380   if ( sockets[sock]->trType == SOCK_STREAM )
00381     {
00382       TCPEndpointReceiveMsg * receiveMsg = ( TCPEndpointReceiveMsg * ) msg;
00383       if ( receiveMsg->error != TCP_SUCCESS )
00384         {
00385           sockets[sock]->state = CONNECTION_ERROR;
00386           close( sock );
00387           return;
00388         }
00389 
00390       sockets[sock]->recvSize = receiveMsg->sizeMin;
00391       if ( sockets[sock]->rcvcbckfn != NULL )
00392         sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00393       sockets[sock]->recvSize = 0;
00394 
00395     }
00396 
00397   else if ( sockets[sock]->trType == SOCK_DGRAM )
00398     {
00399       UDPEndpointReceiveMsg * receiveMsg;
00400       receiveMsg = ( UDPEndpointReceiveMsg * ) antEnvMsg::Receive( msg );
00401       sockets[sock]->recvSize = receiveMsg->size;
00402 
00403       if ( receiveMsg->error == UDP_SUCCESS )
00404         {
00405           // if this UDP connection is not connected yet, connect it
00406           // to the address & port of the computer that sent this message.
00407           // This allows us to send UDP messages to any address instead of
00408           // hard-coding a specific address beforehand
00409 
00410           if ( !strncmp( "connection request", ( char * ) sockets[sock]->recvData, 18 ) )
00411             {
00412               // clear this message from the receiving buffer
00413               sockets[sock]->recvData += sockets[sock]->recvSize;
00414 
00415               if ( sockets[sock]->state != CONNECTION_CONNECTED )
00416                 {
00417                   char caller[14];
00418                   receiveMsg->address.GetAsString( caller );
00419                   connect( sock, caller, receiveMsg->port );
00420                 }
00421             }
00422 
00423           else if ( sockets[sock]->rcvcbckfn != NULL )
00424             sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00425 
00426         }
00427 
00428       sockets[sock]->recvSize = 0;
00429 
00430     }
00431 
00432   receive( sock );
00433 }
00434 
00435 void
00436 Wireless::close(int sock)
00437 {
00438   if (sockets[sock]->state == CONNECTION_CLOSED ||
00439       sockets[sock]->state == CONNECTION_CLOSING) return;
00440 
00441   if (!(sockets[sock]->server_port>0 && sockets[sock]->daemon)) {
00442     sockets[sock]->recvBuffer.UnMap();
00443     antEnvDestroySharedBufferMsg receiveBufferMsg(sockets[sock]->recvBuffer);
00444     receiveBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00445     sockets[sock]->sendBuffer.UnMap();
00446     antEnvDestroySharedBufferMsg sendBufferMsg(sockets[sock]->sendBuffer);
00447     sendBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00448   }
00449 
00450   if ( sockets[sock]->trType == SOCK_STREAM )
00451     {
00452       TCPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00453       closeMsg.continuation = ( void * ) sock;
00454       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00455     }
00456 
00457   else if ( sockets[sock]->trType == SOCK_DGRAM )
00458     {
00459       UDPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00460       closeMsg.continuation = ( void * ) sock;
00461       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00462     }
00463 
00464   sockets[sock]->state = CONNECTION_CLOSING;
00465 }
00466 
00467 void
00468 Wireless::CloseCont(void* msg)
00469 {
00470   antEnvMsg * closeMsg = ( antEnvMsg * ) msg;
00471   int sock = ( int )( closeMsg->continuation );
00472   if ( sockets[sock] == NULL )
00473     return;
00474 
00475   sockets[sock]->state = CONNECTION_CLOSED;
00476   if ( sockets[sock]->server_port > 0 && sockets[sock]->daemon )
00477     {
00478       // recycle if server
00479       listen( sock, sockets[sock]->server_port );
00480     }
00481 
00482   else
00483     {
00484       delete( sockets[sock] );
00485       sockets[sock] = NULL;
00486       freeSockets.push_back( sock );
00487     }
00488 }
00489 
00490 /*! @file
00491  * @brief Interacts with the system to provide networking services
00492  * @author alokl (Creator)
00493  * @author Erik Berglund and Bryan Johnson (UDP support)
00494  * 
00495  * @verbinclude CMPack_license.txt
00496  *
00497  * $Author: ejt $
00498  * $Name: tekkotsu-2_2 $
00499  * $Revision: 1.19 $
00500  * $State: Exp $
00501  * $Date: 2004/09/28 22:12:35 $
00502  */
00503 

Tekkotsu v2.2
Generated Tue Oct 19 14:19:16 2004 by Doxygen 1.3.9.1