Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Wireless.cc

Go to the documentation of this file.
00001 #include "Wireless.h"
00002 #include "Socket.h"
00003 #include <cstring>
00004 #include "Shared/ProjectInterface.h"
00005 
00006 #include "SocketListener.h"
00007 
00008 Wireless *wireless=NULL;
00009 
00010 #ifdef PLATFORM_APERIOS
00011 #  include <OPENR/OSyslog.h>
00012 #  include <OPENR/OPENRAPI.h>
00013 #  include <ant.h>
00014 #  include <EndpointTypes.h>
00015 #  include <TCPEndpointMsg.h>
00016 #  include <UDPEndpointMsg.h>
00017 #  include "aperios/MMCombo/entry.h"
00018 
00019 using namespace std;
00020 
00021 Wireless::Wireless ()
00022   : ipstackRef(), myOID(), freeSockets(), usedSockets()
00023 {
00024   ipstackRef = antStackRef("IPStack");
00025   WhoAmI(&myOID);
00026 
00027   sockets[0]=new DummySocket(0);
00028   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00029     sockets[sock]=NULL;
00030     freeSockets.push_back(sock);
00031   }
00032 }    
00033 
00034 Wireless::~Wireless ()
00035 {
00036   if(usedSockets.size()>0) {
00037     cerr << "WARNING: Wireless deleted with open Sockets" << endl;
00038     for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00039       delete sockets[*it];
00040       sockets[*it]=NULL;
00041     }
00042     freeSockets.insert(freeSockets.end(),usedSockets.begin(),usedSockets.end());
00043     usedSockets.clear();
00044   }
00045 }
00046 
00047 Socket* Wireless::socket(Socket::TransportType_t ttype)
00048 {
00049   return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00050 }
00051 
00052 Socket* Wireless::socket(Socket::TransportType_t ttype, int recvsize, int sendsize)
00053 {
00054   if (freeSockets.empty()
00055       || (recvsize + sendsize) <= 256) return sockets[0];
00056   int sock_num=freeSockets.front();
00057   freeSockets.pop_front();
00058   usedSockets.push_back(sock_num);
00059 
00060   sockets[sock_num]=new Socket(sock_num);
00061   sockets[sock_num]->sendBufSize=sendsize;
00062   sockets[sock_num]->recvBufSize=recvsize;
00063   sockets[sock_num]->setTransport(ttype);
00064 
00065   // setup send buffer
00066   antEnvCreateSharedBufferMsg sendBufferMsg(sendsize*2);
00067   sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00068   if (sendBufferMsg.error != ANT_SUCCESS) return sockets[0];
00069 
00070   sockets[sock_num]->sendBuffer = sendBufferMsg.buffer;
00071   sockets[sock_num]->sendBuffer.Map();
00072   sockets[sock_num]->sendData = ( byte * ) ( sockets[sock_num]->sendBuffer.GetAddress() );
00073 
00074   // setup receive buffer
00075   antEnvCreateSharedBufferMsg recvBufferMsg(recvsize*2);
00076   recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00077   if (recvBufferMsg.error != ANT_SUCCESS) return sockets[0];
00078 
00079   sockets[sock_num]->recvBuffer = recvBufferMsg.buffer;
00080   sockets[sock_num]->recvBuffer.Map();
00081   sockets[sock_num]->recvData = ( byte * ) ( sockets[sock_num]->recvBuffer.GetAddress() );
00082 
00083   sockets[sock_num]->readData = sockets[sock_num]->recvData + recvsize;
00084   sockets[sock_num]->writeData = sockets[sock_num]->sendData + sendsize;
00085 
00086   return sockets[sock_num]; 
00087 }
00088 
00089 int Wireless::listen(int sock, int port)
00090 {
00091   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00092        || sockets[sock]->state != Socket::CONNECTION_CLOSED )return -1;
00093 
00094   sockets[sock]->server_port = port;
00095   sockets[sock]->init();
00096 
00097   if (sockets[sock]->trType==Socket::SOCK_STREAM) {
00098     // create endpoint
00099     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00100     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00101     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00102     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00103 
00104     // listen
00105     TCPEndpointListenMsg listenMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00106     listenMsg.continuation = ( void * ) sock;
00107 
00108     listenMsg.Send( ipstackRef, myOID, Extra_Entry[entryListenCont], sizeof( listenMsg ) );
00109 
00110     sockets[sock]->state = Socket::CONNECTION_LISTENING;
00111     return 0;
00112   } else if (sockets[sock]->trType==Socket::SOCK_DGRAM) {
00113     // create endpoint
00114     antEnvCreateEndpointMsg udpCreateMsg( EndpointType_UDP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00115     udpCreateMsg.Call( ipstackRef, sizeof( udpCreateMsg ) );
00116     if ( udpCreateMsg.error != ANT_SUCCESS ) return -1;
00117 
00118     // bind socket
00119     sockets[sock]->endpoint = udpCreateMsg.moduleRef;
00120     UDPEndpointBindMsg bindMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00121     bindMsg.Call( ipstackRef, sizeof( bindMsg ) );
00122     bindMsg.continuation = ( void * ) sock;
00123 
00124     sockets[sock]->state = Socket::CONNECTION_CONNECTING;
00125 
00126     receive( sock );
00127 
00128     return 0;
00129 
00130   }
00131 
00132   else
00133     return -1;
00134 }
00135 
00136 /** Tell the ipstack we want to recieve messages with this function. */
00137 
00138 int Wireless::connect( int sock, const char * ipaddr, int port )
00139 {
00140   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00141        || ( sockets[sock]->trType == Socket::SOCK_STREAM && sockets[sock]->state != Socket::CONNECTION_CLOSED ) ) return -1;
00142 
00143   sockets[sock]->init();
00144   if (sockets[sock]->trType==Socket::SOCK_STREAM) {
00145     // create endpoint
00146     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00147     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00148     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00149     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00150 
00151     // connect
00152     TCPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, IP_ADDR_ANY, IP_PORT_ANY, ipaddr, port );
00153     connectMsg.continuation = ( void * ) sock;
00154 
00155     connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00156     sockets[sock]->peer_addr=connectMsg.fAddress.Address();
00157     sockets[sock]->peer_port=connectMsg.fPort;
00158 
00159     sockets[sock]->state = Socket::CONNECTION_CONNECTING;
00160     return 0;
00161   }
00162 
00163   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00164     {
00165       // connect
00166       UDPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, ipaddr, port );
00167 
00168       connectMsg.continuation = ( void * ) sock;
00169 
00170       connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00171       sockets[sock]->peer_addr=connectMsg.address.Address();
00172       sockets[sock]->peer_port=connectMsg.port;
00173 
00174       sockets[sock]->state = Socket::CONNECTION_CONNECTED;
00175       //std::cout << "Sock " << sock << " connected via UDP to IP " << ipaddr << " port " << port << std::flush << std::endl;
00176 
00177       return 0;
00178     }
00179 
00180   else
00181     {
00182       return -1;
00183     }
00184 }
00185 
00186 void
00187 Wireless::ListenCont(void* msg)
00188 {
00189 try {
00190   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00191   int sock = ( int )( Msg->continuation );
00192 
00193   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00194     {
00195       TCPEndpointListenMsg * listenMsg = ( TCPEndpointListenMsg * ) antEnvMsg::Receive( msg );
00196 
00197       if ( listenMsg->error != TCP_SUCCESS )
00198         {
00199           sockets[sock]->state = Socket::CONNECTION_ERROR;
00200 
00201           // no use recycling since its a resource issue
00202           return;
00203         }
00204       sockets[sock]->peer_addr=listenMsg->fAddress.Address();
00205       sockets[sock]->peer_port=listenMsg->fPort;
00206 
00207       sockets[sock]->state = Socket::CONNECTION_CONNECTED;
00208       //sockets[sock]->local_ipaddr = listenMsg->lAddress.Address();
00209       //cout << "Listen set lip: " << local_ipaddr << endl;
00210       receive( sock );
00211     }
00212 
00213 } catch(const std::exception& ex) {
00214   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Listen callback",&ex))
00215     throw;
00216 } catch(...) {
00217   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Listen callback",NULL))
00218     throw;
00219 }
00220 }
00221 
00222 void
00223 Wireless::ConnectCont(void *msg)
00224 {
00225 try {
00226   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00227   int sock = ( int )( Msg->continuation );
00228 
00229   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00230     {
00231       TCPEndpointConnectMsg * connectMsg = ( TCPEndpointConnectMsg * ) antEnvMsg::Receive( msg );
00232       if ( connectMsg->error != TCP_SUCCESS )
00233         {
00234           sockets[sock]->state = Socket::CONNECTION_ERROR;
00235           return;
00236         }
00237 
00238       sockets[sock]->state = Socket::CONNECTION_CONNECTED;
00239       //sockets[sock]->local_ipaddr = connectMsg->lAddress.Address();
00240       //cout << "Connect set lip: " << local_ipaddr << endl;
00241       receive( sock );
00242     }
00243 
00244 } catch(const std::exception& ex) {
00245   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Connect callback",&ex))
00246     throw;
00247 } catch(...) {
00248   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Connect callback",NULL))
00249     throw;
00250 }
00251 }
00252 
00253 void
00254 Wireless::BindCont(void *msg)
00255 {
00256 try {
00257   UDPEndpointBindMsg* bindMsg = (UDPEndpointBindMsg*) antEnvMsg::Receive( msg );
00258   int sock = (int)bindMsg->continuation;
00259 
00260   if (bindMsg->error != UDP_SUCCESS) {
00261     sockets[sock]->state = Socket::CONNECTION_ERROR;
00262     return;
00263   }
00264 
00265   sockets[sock]->state = Socket::CONNECTION_CONNECTED;
00266   /*  if(bindMsg->address.Address()!=0) {
00267     //sockets[sock]->local_ipaddr = bindMsg->address.Address();
00268     //cout << "Bind set lip: " << local_ipaddr << endl;
00269   } else {
00270     //cout << "Bind got 0" << endl;
00271     }*/
00272 
00273 } catch(const std::exception& ex) {
00274   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Bind callback",&ex))
00275     throw;
00276 } catch(...) {
00277   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Bind callback",NULL))
00278     throw;
00279 }
00280 }
00281 
00282 void
00283 Wireless::send(int sock)
00284 {
00285   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != Socket::CONNECTION_CONNECTED
00286        || sockets[sock]->sendSize <= 0 ) return;
00287 
00288   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00289     {
00290       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00291       sendMsg.continuation = ( void * ) sock;
00292 
00293       sockets[sock]->tx = true;
00294       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( TCPEndpointSendMsg ) );
00295       sockets[sock]->sendSize = 0;
00296     }
00297 
00298   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00299     {
00300       UDPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00301 
00302       // this field is just hijacked to id the socket # this message is being sent across
00303       sendMsg.continuation = ( void * ) sock;
00304 
00305       sockets[sock]->tx = true;
00306       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( UDPEndpointSendMsg ) );
00307       sockets[sock]->sendSize = 0;
00308     }
00309 }
00310 
00311 void
00312 Wireless::SendCont(void* msg)
00313 {
00314 try {
00315   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00316   int sock = ( int )( Msg->continuation );
00317 
00318   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00319     {
00320       TCPEndpointSendMsg * sendMsg = ( TCPEndpointSendMsg * ) antEnvMsg::Receive( msg );
00321       sockets[sock]->tx = false;
00322       if ( sendMsg->error != TCP_SUCCESS )
00323         {
00324           sockets[sock]->state = Socket::CONNECTION_ERROR;
00325           close( sock );
00326           return;
00327         }
00328     }
00329 
00330   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00331     {
00332       UDPEndpointSendMsg * sendMsg = ( UDPEndpointSendMsg * ) antEnvMsg::Receive( msg );
00333       sockets[sock]->tx = false;
00334       if ( sendMsg->error != UDP_SUCCESS )
00335         {
00336           sockets[sock]->state = Socket::CONNECTION_ERROR;
00337           close( sock );
00338           return;
00339         }
00340     }
00341 
00342   sockets[sock]->flush();
00343 
00344 } catch(const std::exception& ex) {
00345   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Send callback",&ex))
00346     throw;
00347 } catch(...) {
00348   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Send callback",NULL))
00349     throw;
00350 }
00351 }
00352 
00353 /*! @bug This doesn't actually seem to block until the message is
00354 * fully sent... a crash immediately after this will still cause a
00355 * line or two to be dropped.  This is still less dropped than
00356 * regular send, but doesn't do much good for debugging until we fix
00357 * this. (if we can...) */
00358 void
00359 Wireless::blockingSend(int sock)
00360 {
00361   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != Socket::CONNECTION_CONNECTED
00362        || sockets[sock]->sendSize <= 0 ) return;
00363 
00364   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00365     {
00366       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00367       sendMsg.continuation = ( void * ) sock;
00368 
00369       sockets[sock]->tx=true;
00370       sockets[sock]->sendSize = 0;
00371       sendMsg.Call( ipstackRef, sizeof( TCPEndpointSendMsg ) );
00372       sockets[sock]->tx = false;
00373     }
00374 
00375   // no double buffering
00376 }
00377 
00378 void
00379 Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) )
00380 {
00381   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL) return;
00382 
00383   sockets[sock]->rcvcbckfn=rcvcbckfn;
00384 }
00385 
00386 void Wireless::setReceiver(int sock, SocketListener *listener) {
00387   if (sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL)
00388     return;
00389   
00390   sockets[sock]->sckListener = listener;
00391 }
00392 
00393 void
00394 Wireless::receive(int sock)
00395 {
00396   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00397        || ( sockets[sock]->trType == Socket::SOCK_STREAM && sockets[sock]->state != Socket::CONNECTION_CONNECTED ) )
00398     return;
00399 
00400   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00401     {
00402       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00403       receiveMsg.continuation = ( void * ) sock;
00404       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00405     }
00406 
00407   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00408     {
00409       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00410       receiveMsg.continuation = ( void * ) sock;
00411       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00412     }
00413 
00414   sockets[sock]->rx = true;
00415 }
00416 
00417 void
00418 Wireless::receive(int sock, int (*rcvcbckfn) (char*, int) )
00419 {
00420   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00421       || sockets[sock]->state != Socket::CONNECTION_CONNECTED) return;
00422 
00423   sockets[sock]->rcvcbckfn = rcvcbckfn;
00424 
00425   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00426     {
00427       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00428       receiveMsg.continuation = ( void * ) sock;
00429       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00430     }
00431 
00432   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00433     {
00434       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00435       receiveMsg.continuation = ( void * ) sock;
00436       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00437     }
00438 
00439   sockets[sock]->rx = true;
00440 }
00441 
00442 void
00443 Wireless::ReceiveCont(void* msg)
00444 {
00445 try {
00446   // get the socket index before casting the message into UDP or TCP form
00447   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00448   int sock = ( int )( Msg->continuation );
00449 
00450   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00451        || ( sockets[sock]->state != Socket::CONNECTION_CONNECTED && sockets[sock]->state != Socket::CONNECTION_CONNECTING ) )
00452     return;
00453 
00454   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00455     {
00456       TCPEndpointReceiveMsg * receiveMsg = ( TCPEndpointReceiveMsg * ) antEnvMsg::Receive( msg );
00457       if ( receiveMsg->error != TCP_SUCCESS )
00458         {
00459           sockets[sock]->state = Socket::CONNECTION_ERROR;
00460           close( sock );
00461           return;
00462         }
00463 
00464       sockets[sock]->recvSize = receiveMsg->sizeMin;
00465       
00466       if (sockets[sock]->sckListener != NULL) {
00467         sockets[sock]->sckListener->processData((char *)sockets[sock]->recvData,
00468                             sockets[sock]->recvSize);
00469         
00470       } else if (sockets[sock]->rcvcbckfn != NULL) {
00471         sockets[sock]->rcvcbckfn((char *)sockets[sock]->recvData,
00472                      sockets[sock]->recvSize);
00473       }
00474       sockets[sock]->recvSize = 0;
00475 
00476     }
00477 
00478   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00479     {
00480       UDPEndpointReceiveMsg * receiveMsg;
00481       receiveMsg = ( UDPEndpointReceiveMsg * ) antEnvMsg::Receive( msg );
00482       sockets[sock]->recvSize = receiveMsg->size;
00483 
00484       if ( receiveMsg->error == UDP_SUCCESS )
00485         {
00486           // if this UDP connection is not connected yet, connect it
00487           // to the address & port of the computer that sent this message.
00488           // This allows us to send UDP messages to any address instead of
00489           // hard-coding a specific address beforehand
00490 
00491           sockets[sock]->peer_addr=receiveMsg->address.Address();
00492           sockets[sock]->peer_port=receiveMsg->port;
00493           if ( !strncmp( "connection request", ( char * ) sockets[sock]->recvData, 18 ) ) {
00494             // clear this message from the receiving buffer
00495             sockets[sock]->recvData += sockets[sock]->recvSize;
00496             
00497             if ( sockets[sock]->state != Socket::CONNECTION_CONNECTED ) {
00498               char caller[14];
00499               receiveMsg->address.GetAsString( caller );
00500               connect( sock, caller, receiveMsg->port );
00501             }
00502             
00503           } else if (sockets[sock]->sckListener != NULL) {
00504             sockets[sock]->sckListener->processData((char *)sockets[sock]->recvData, sockets[sock]->recvSize);
00505             
00506           } else if ( sockets[sock]->rcvcbckfn != NULL )
00507             sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00508           
00509         }
00510 
00511       sockets[sock]->recvSize = 0;
00512 
00513     }
00514 
00515   receive( sock );
00516 
00517 } catch(const std::exception& ex) {
00518   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Receive callback",&ex))
00519     throw;
00520 } catch(...) {
00521   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Receive callback",NULL))
00522     throw;
00523 }
00524 }
00525 
00526 void
00527 Wireless::close(int sock)
00528 {
00529   if (sockets[sock]->state == Socket::CONNECTION_CLOSED ||
00530       sockets[sock]->state == Socket::CONNECTION_CLOSING) return;
00531 
00532   if (!(sockets[sock]->server_port>0 && sockets[sock]->daemon)) {
00533     sockets[sock]->recvBuffer.UnMap();
00534     antEnvDestroySharedBufferMsg receiveBufferMsg(sockets[sock]->recvBuffer);
00535     receiveBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00536     sockets[sock]->sendBuffer.UnMap();
00537     antEnvDestroySharedBufferMsg sendBufferMsg(sockets[sock]->sendBuffer);
00538     sendBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00539   }
00540 
00541   if ( sockets[sock]->trType == Socket::SOCK_STREAM )
00542     {
00543       TCPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00544       closeMsg.continuation = ( void * ) sock;
00545       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00546     }
00547 
00548   else if ( sockets[sock]->trType == Socket::SOCK_DGRAM )
00549     {
00550       UDPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00551       closeMsg.continuation = ( void * ) sock;
00552       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00553     }
00554 
00555   sockets[sock]->peer_addr=sockets[sock]->peer_port=-1;
00556 
00557   sockets[sock]->state = Socket::CONNECTION_CLOSING;
00558 }
00559 
00560 uint32
00561 Wireless::getIPAddress(unsigned int /*idx=0*/) {
00562   uint32 local_ipaddr=0;
00563   //from OPEN-R sample ERA201D1Info:
00564   antEnvInitGetParamMsg getParamMsg("ETHER_IP");
00565   getParamMsg.Call(ipstackRef, sizeof(getParamMsg));
00566   if (getParamMsg.error == ANT_SUCCESS && getParamMsg.paramType == antEnv_InitParam_String) {
00567     //cout << "******** RECEIVED " << getParamMsg.value.str << endl;
00568     unsigned int i=0;
00569     for(int j=3; j>=0; j--) {
00570       unsigned int b=0;
00571       while(i<ANTENV_VALUE_LENGTH_MAX && getParamMsg.value.str[i]!='.' && getParamMsg.value.str[i]!='\0')
00572         b=b*10+(getParamMsg.value.str[i++]-'0');
00573       i++; //skip over '.'
00574       local_ipaddr+=b<<(j*8);
00575       //cout << j << ": " << b << ' ' << local_ipaddr << endl;
00576     }
00577   } else {
00578     OSYSLOG1((osyslogERROR,"getParamMsg.Call() FAILED %d", getParamMsg.error));
00579   }
00580   return local_ipaddr;
00581 }
00582 
00583 void
00584 Wireless::CloseCont(void* msg)
00585 {
00586 try {
00587   antEnvMsg * closeMsg = ( antEnvMsg * ) antEnvMsg::Receive( msg );
00588   int sock = ( int )( closeMsg->continuation );
00589   if ( sockets[sock] == NULL )
00590     return;
00591 
00592   sockets[sock]->state = Socket::CONNECTION_CLOSED;
00593   sockets[sock]->peer_addr=sockets[sock]->peer_port=-1;
00594   if ( sockets[sock]->server_port > 0 && sockets[sock]->daemon )
00595     {
00596       // recycle if server
00597       listen( sock, sockets[sock]->server_port );
00598     }
00599 
00600   else
00601     {
00602       delete( sockets[sock] );
00603       sockets[sock] = NULL;
00604       freeSockets.push_back( sock );
00605       for(list<int>::iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it)
00606         if(*it==sock) {
00607           usedSockets.erase(it);
00608           break;
00609         }
00610     }
00611 
00612 } catch(const std::exception& ex) {
00613   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Close callback",&ex))
00614     throw;
00615 } catch(...) {
00616   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Close callback",NULL))
00617     throw;
00618 }
00619 }
00620 
00621 #else // PLATFORM_LOCAL
00622 #  include "IPC/Thread.h"
00623 #  include <sys/types.h>
00624 #  include <sys/socket.h>
00625 #  include <netinet/in.h>
00626 #  include <netdb.h>
00627 #  include <arpa/inet.h>
00628 #  include <fcntl.h>
00629 #  include <unistd.h>
00630 #  include <iostream>
00631 #  include <errno.h>
00632 #  include "Shared/MarkScope.h"
00633 
00634 using namespace std;
00635 
00636 
00637 Wireless::Wireless ()
00638   : callbackLock(NULL), interruptChk(-1), interruptCtl(-1), rfds(), wfds(), efds(), fdsMax(0), freeSockets(), usedSockets()
00639 {
00640   sockets[0]=new DummySocket(0);
00641   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00642     sockets[sock]=NULL;
00643     freeSockets.push_back(sock);
00644   }
00645   int p[2];
00646   pipe(p);
00647   interruptChk=p[0];
00648   interruptCtl=p[1];
00649   fdsMax=interruptChk;
00650   if( ::fcntl(interruptChk,F_SETFL,O_NONBLOCK) ==-1 ) {
00651     perror("Wireless::Wireless(): fcntl");
00652   }
00653   FD_ZERO(&rfds);
00654   FD_SET(interruptChk,&rfds);
00655   FD_ZERO(&wfds);
00656   FD_ZERO(&efds);
00657 }
00658 
00659 Wireless::~Wireless ()
00660 {
00661   MarkScope l(getLock());
00662 	::close(interruptChk);
00663 	::close(interruptCtl);
00664   interruptChk=interruptCtl=-1;
00665   if(usedSockets.size()>0) {
00666     cerr << "WARNING: Wireless deleted with open Sockets" << endl;
00667     for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00668       delete sockets[*it];
00669       sockets[*it]=NULL;
00670     }
00671     freeSockets.insert(freeSockets.end(),usedSockets.begin(),usedSockets.end());
00672     usedSockets.clear();
00673   }
00674   delete sockets[0]; // DummySocket
00675 }
00676 
00677 void