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       //sockets[sock]->local_ipaddr = listenMsg->lAddress.Address();
00188       //cout << "Listen set lip: " << local_ipaddr << endl;
00189       receive( sock );
00190     }
00191 }
00192 
00193 void
00194 Wireless::ConnectCont(void *msg)
00195 {
00196   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00197   int sock = ( int )( Msg->continuation );
00198 
00199   if ( sockets[sock]->trType == SOCK_STREAM )
00200     {
00201       TCPEndpointConnectMsg * connectMsg = ( TCPEndpointConnectMsg * ) msg;
00202       if ( connectMsg->error != TCP_SUCCESS )
00203         {
00204           sockets[sock]->state = CONNECTION_ERROR;
00205           return;
00206         }
00207 
00208       sockets[sock]->state = CONNECTION_CONNECTED;
00209       //sockets[sock]->local_ipaddr = connectMsg->lAddress.Address();
00210       //cout << "Connect set lip: " << local_ipaddr << endl;
00211       receive( sock );
00212     }
00213 }
00214 
00215 void
00216 Wireless::BindCont(void *msg)
00217 {
00218   UDPEndpointBindMsg* bindMsg = (UDPEndpointBindMsg*)msg;
00219   int sock = (int)bindMsg->continuation;
00220 
00221   if (bindMsg->error != UDP_SUCCESS) {
00222     sockets[sock]->state = CONNECTION_ERROR;
00223     return;
00224   }
00225 
00226   sockets[sock]->state = CONNECTION_CONNECTED;
00227   /*  if(bindMsg->address.Address()!=0) {
00228     //sockets[sock]->local_ipaddr = bindMsg->address.Address();
00229     //cout << "Bind set lip: " << local_ipaddr << endl;
00230   } else {
00231     //cout << "Bind got 0" << endl;
00232     }*/
00233 }
00234 
00235 void
00236 Wireless::send(int sock)
00237 {
00238   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00239        || sockets[sock]->sendSize <= 0 ) return;
00240 
00241   if ( sockets[sock]->trType == SOCK_STREAM )
00242     {
00243       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00244       sendMsg.continuation = ( void * ) sock;
00245 
00246       sockets[sock]->tx = true;
00247       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( TCPEndpointSendMsg ) );
00248       sockets[sock]->sendSize = 0;
00249     }
00250 
00251   else if ( sockets[sock]->trType == SOCK_DGRAM )
00252     {
00253       UDPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00254 
00255       // this field is just hijacked to id the socket # this message is being sent across
00256       sendMsg.continuation = ( void * ) sock;
00257 
00258       sockets[sock]->tx = true;
00259       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( UDPEndpointSendMsg ) );
00260       sockets[sock]->sendSize = 0;
00261     }
00262 }
00263 
00264 void
00265 Wireless::SendCont(void* msg)
00266 {
00267   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00268   int sock = ( int )( Msg->continuation );
00269 
00270   if ( sockets[sock]->trType == SOCK_STREAM )
00271     {
00272       TCPEndpointSendMsg * sendMsg = ( TCPEndpointSendMsg * ) msg;
00273       sockets[sock]->tx = false;
00274       if ( sendMsg->error != TCP_SUCCESS )
00275         {
00276           sockets[sock]->state = CONNECTION_ERROR;
00277           close( sock );
00278           return;
00279         }
00280     }
00281 
00282   else if ( sockets[sock]->trType == SOCK_DGRAM )
00283     {
00284       UDPEndpointSendMsg * sendMsg = ( UDPEndpointSendMsg * ) msg;
00285       sockets[sock]->tx = false;
00286       if ( sendMsg->error != UDP_SUCCESS )
00287         {
00288           sockets[sock]->state = CONNECTION_ERROR;
00289           close( sock );
00290           return;
00291         }
00292     }
00293 
00294   sockets[sock]->flush();
00295 }
00296 
00297 /*! @bug This doesn't actually seem to block until the message is
00298 * fully sent... a crash immediately after this will still cause a
00299 * line or two to be dropped.  This is still less dropped than
00300 * regular send, but doesn't do much good for debugging until we fix
00301 * this. (if we can...) */
00302 void
00303 Wireless::blockingSend(int sock)
00304 {
00305   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00306        || sockets[sock]->sendSize <= 0 ) return;
00307 
00308   if ( sockets[sock]->trType == SOCK_STREAM )
00309     {
00310       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00311       sendMsg.continuation = ( void * ) sock;
00312 
00313       sockets[sock]->tx=true;
00314       sockets[sock]->sendSize = 0;
00315       sendMsg.Call( ipstackRef, sizeof( TCPEndpointSendMsg ) );
00316       sockets[sock]->tx = false;
00317     }
00318 
00319   // no double buffering
00320 }
00321 
00322 void
00323 Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) )
00324 {
00325   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL) return;
00326 
00327   sockets[sock]->rcvcbckfn=rcvcbckfn;
00328 }
00329 
00330 void
00331 Wireless::receive(int sock)
00332 {
00333   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00334        || ( sockets[sock]->trType == SOCK_STREAM && sockets[sock]->state != CONNECTION_CONNECTED ) )
00335     return;
00336 
00337   if ( sockets[sock]->trType == SOCK_STREAM )
00338     {
00339       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00340       receiveMsg.continuation = ( void * ) sock;
00341       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00342     }
00343 
00344   else if ( sockets[sock]->trType == SOCK_DGRAM )
00345     {
00346       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00347       receiveMsg.continuation = ( void * ) sock;
00348       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00349     }
00350 
00351   sockets[sock]->rx = true;
00352 }
00353 
00354 void
00355 Wireless::receive(int sock, int (*rcvcbckfn) (char*, int) )
00356 {
00357   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00358       || sockets[sock]->state != CONNECTION_CONNECTED) return;
00359 
00360   sockets[sock]->rcvcbckfn = rcvcbckfn;
00361 
00362   if ( sockets[sock]->trType == SOCK_STREAM )
00363     {
00364       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00365       receiveMsg.continuation = ( void * ) sock;
00366       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00367     }
00368 
00369   else if ( sockets[sock]->trType == SOCK_DGRAM )
00370     {
00371       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00372       receiveMsg.continuation = ( void * ) sock;
00373       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00374     }
00375 
00376   sockets[sock]->rx = true;
00377 }
00378 
00379 void
00380 Wireless::ReceiveCont(void* msg)
00381 {
00382   // get the socket index before casting the message into UDP or TCP form
00383   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00384   int sock = ( int )( Msg->continuation );
00385 
00386   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00387        || ( sockets[sock]->state != CONNECTION_CONNECTED && sockets[sock]->state != CONNECTION_CONNECTING ) )
00388     return;
00389 
00390   if ( sockets[sock]->trType == SOCK_STREAM )
00391     {
00392       TCPEndpointReceiveMsg * receiveMsg = ( TCPEndpointReceiveMsg * ) msg;
00393       if ( receiveMsg->error != TCP_SUCCESS )
00394         {
00395           sockets[sock]->state = CONNECTION_ERROR;
00396           close( sock );
00397           return;
00398         }
00399 
00400       sockets[sock]->recvSize = receiveMsg->sizeMin;
00401       if ( sockets[sock]->rcvcbckfn != NULL )
00402         sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00403       sockets[sock]->recvSize = 0;
00404 
00405     }
00406 
00407   else if ( sockets[sock]->trType == SOCK_DGRAM )
00408     {
00409       UDPEndpointReceiveMsg * receiveMsg;
00410       receiveMsg = ( UDPEndpointReceiveMsg * ) antEnvMsg::Receive( msg );
00411       sockets[sock]->recvSize = receiveMsg->size;
00412 
00413       if ( receiveMsg->error == UDP_SUCCESS )
00414         {
00415           // if this UDP connection is not connected yet, connect it
00416           // to the address & port of the computer that sent this message.
00417           // This allows us to send UDP messages to any address instead of
00418           // hard-coding a specific address beforehand
00419 
00420           if ( !strncmp( "connection request", ( char * ) sockets[sock]->recvData, 18 ) )
00421             {
00422               // clear this message from the receiving buffer
00423               sockets[sock]->recvData += sockets[sock]->recvSize;
00424 
00425               if ( sockets[sock]->state != CONNECTION_CONNECTED )
00426                 {
00427                   char caller[14];
00428                   receiveMsg->address.GetAsString( caller );
00429                   connect( sock, caller, receiveMsg->port );
00430                 }
00431             }
00432 
00433           else if ( sockets[sock]->rcvcbckfn != NULL )
00434             sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00435 
00436         }
00437 
00438       sockets[sock]->recvSize = 0;
00439 
00440     }
00441 
00442   receive( sock );
00443 }
00444 
00445 void
00446 Wireless::close(int sock)
00447 {
00448   if (sockets[sock]->state == CONNECTION_CLOSED ||
00449       sockets[sock]->state == CONNECTION_CLOSING) return;
00450 
00451   if (!(sockets[sock]->server_port>0 && sockets[sock]->daemon)) {
00452     sockets[sock]->recvBuffer.UnMap();
00453     antEnvDestroySharedBufferMsg receiveBufferMsg(sockets[sock]->recvBuffer);
00454     receiveBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00455     sockets[sock]->sendBuffer.UnMap();
00456     antEnvDestroySharedBufferMsg sendBufferMsg(sockets[sock]->sendBuffer);
00457     sendBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00458   }
00459 
00460   if ( sockets[sock]->trType == SOCK_STREAM )
00461     {
00462       TCPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00463       closeMsg.continuation = ( void * ) sock;
00464       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00465     }
00466 
00467   else if ( sockets[sock]->trType == SOCK_DGRAM )
00468     {
00469       UDPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00470       closeMsg.continuation = ( void * ) sock;
00471       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00472     }
00473 
00474   sockets[sock]->state = CONNECTION_CLOSING;
00475 }
00476 
00477 uint32
00478 Wireless::getIPAddress(unsigned int /*idx=0*/) {
00479   uint32 local_ipaddr=0;
00480   //from OPEN-R sample ERA201D1Info:
00481   antEnvInitGetParamMsg getParamMsg("ETHER_IP");
00482   getParamMsg.Call(ipstackRef, sizeof(getParamMsg));
00483   if (getParamMsg.error == ANT_SUCCESS && getParamMsg.paramType == antEnv_InitParam_String) {
00484     //cout << "******** RECEIVED " << getParamMsg.value.str << endl;
00485     unsigned int i=0;
00486     for(int j=3; j>=0; j--) {
00487       unsigned int b=0;
00488       while(i<ANTENV_VALUE_LENGTH_MAX && getParamMsg.value.str[i]!='.' && getParamMsg.value.str[i]!='\0')
00489         b=b*10+(getParamMsg.value.str[i++]-'0');
00490       i++; //skip over '.'
00491       local_ipaddr+=b<<(j*8);
00492       //cout << j << ": " << b << ' ' << local_ipaddr << endl;
00493     }
00494   } else {
00495     OSYSLOG1((osyslogERROR,"getParamMsg.Call() FAILED %d", getParamMsg.error));
00496   }
00497   return local_ipaddr;
00498 }
00499 
00500 void
00501 Wireless::CloseCont(void* msg)
00502 {
00503   antEnvMsg * closeMsg = ( antEnvMsg * ) msg;
00504   int sock = ( int )( closeMsg->continuation );
00505   if ( sockets[sock] == NULL )
00506     return;
00507 
00508   sockets[sock]->state = CONNECTION_CLOSED;
00509   if ( sockets[sock]->server_port > 0 && sockets[sock]->daemon )
00510     {
00511       // recycle if server
00512       listen( sock, sockets[sock]->server_port );
00513     }
00514 
00515   else
00516     {
00517       delete( sockets[sock] );
00518       sockets[sock] = NULL;
00519       freeSockets.push_back( sock );
00520     }
00521 }
00522 
00523 /*! @file
00524  * @brief Interacts with the system to provide networking services
00525  * @author alokl (Creator)
00526  * @author Erik Berglund and Bryan Johnson (UDP support)
00527  * 
00528  * @verbinclude CMPack_license.txt
00529  *
00530  * $Author: ejt $
00531  * $Name: tekkotsu-2_3 $
00532  * $Revision: 1.21 $
00533  * $State: Exp $
00534  * $Date: 2005/01/27 05:40:45 $
00535  */
00536 

Tekkotsu v2.3
Generated Sat Jan 29 02:25:24 2005 by Doxygen 1.4.0