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 Wireless *wireless=NULL;
00007 
00008 #ifdef PLATFORM_APERIOS
00009 #  include <OPENR/OSyslog.h>
00010 #  include <OPENR/OPENRAPI.h>
00011 #  include <ant.h>
00012 #  include <EndpointTypes.h>
00013 #  include <TCPEndpointMsg.h>
00014 #  include <UDPEndpointMsg.h>
00015 #  include "aperios/MMCombo/entry.h"
00016 
00017 using namespace SocketNS;
00018 using namespace std;
00019 
00020 Wireless::Wireless ()
00021   : ipstackRef(), myOID(), freeSockets(), usedSockets()
00022 {
00023   ipstackRef = antStackRef("IPStack");
00024   WhoAmI(&myOID);
00025 
00026   sockets[0]=new DummySocket(0);
00027   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00028     sockets[sock]=NULL;
00029     freeSockets.push_back(sock);
00030   }
00031 }    
00032 
00033 Wireless::~Wireless ()
00034 {
00035   if(usedSockets.size()>0) {
00036     cerr << "WARNING: Wireless deleted with open Sockets" << endl;
00037     for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00038       delete sockets[*it];
00039       sockets[*it]=NULL;
00040     }
00041     freeSockets.insert(freeSockets.end(),usedSockets.begin(),usedSockets.end());
00042     usedSockets.clear();
00043   }
00044 }
00045 
00046 Socket* Wireless::socket(TransportType_t ttype)
00047 {
00048   return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00049 }
00050 
00051 Socket* Wireless::socket(TransportType_t ttype, int recvsize, int sendsize)
00052 {
00053   if (freeSockets.empty()
00054       || (recvsize + sendsize) <= 256) return sockets[0];
00055   int sock_num=freeSockets.front();
00056   freeSockets.pop_front();
00057   usedSockets.push_back(sock_num);
00058 
00059   sockets[sock_num]=new Socket(sock_num);
00060   sockets[sock_num]->sendBufSize=sendsize;
00061   sockets[sock_num]->recvBufSize=recvsize;
00062   sockets[sock_num]->setTransport(ttype);
00063 
00064   // setup send buffer
00065   antEnvCreateSharedBufferMsg sendBufferMsg(sendsize*2);
00066   sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00067   if (sendBufferMsg.error != ANT_SUCCESS) return sockets[0];
00068 
00069   sockets[sock_num]->sendBuffer = sendBufferMsg.buffer;
00070   sockets[sock_num]->sendBuffer.Map();
00071   sockets[sock_num]->sendData = ( byte * ) ( sockets[sock_num]->sendBuffer.GetAddress() );
00072 
00073   // setup receive buffer
00074   antEnvCreateSharedBufferMsg recvBufferMsg(recvsize*2);
00075   recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00076   if (recvBufferMsg.error != ANT_SUCCESS) return sockets[0];
00077 
00078   sockets[sock_num]->recvBuffer = recvBufferMsg.buffer;
00079   sockets[sock_num]->recvBuffer.Map();
00080   sockets[sock_num]->recvData = ( byte * ) ( sockets[sock_num]->recvBuffer.GetAddress() );
00081 
00082   sockets[sock_num]->readData = sockets[sock_num]->recvData + recvsize;
00083   sockets[sock_num]->writeData = sockets[sock_num]->sendData + sendsize;
00084 
00085   return sockets[sock_num]; 
00086 }
00087 
00088 int Wireless::listen(int sock, int port)
00089 {
00090   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00091        || sockets[sock]->state != CONNECTION_CLOSED )return -1;
00092 
00093   sockets[sock]->server_port = port;
00094   sockets[sock]->init();
00095 
00096   if (sockets[sock]->trType==SocketNS::SOCK_STREAM) {
00097     // create endpoint
00098     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00099     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00100     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00101     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00102 
00103     // listen
00104     TCPEndpointListenMsg listenMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00105     listenMsg.continuation = ( void * ) sock;
00106 
00107     listenMsg.Send( ipstackRef, myOID, Extra_Entry[entryListenCont], sizeof( listenMsg ) );
00108 
00109     sockets[sock]->state = CONNECTION_LISTENING;
00110     return 0;
00111   } else if (sockets[sock]->trType==SOCK_DGRAM) {
00112     // create endpoint
00113     antEnvCreateEndpointMsg udpCreateMsg( EndpointType_UDP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00114     udpCreateMsg.Call( ipstackRef, sizeof( udpCreateMsg ) );
00115     if ( udpCreateMsg.error != ANT_SUCCESS ) return -1;
00116 
00117     // bind socket
00118     sockets[sock]->endpoint = udpCreateMsg.moduleRef;
00119     UDPEndpointBindMsg bindMsg( sockets[sock]->endpoint, IP_ADDR_ANY, port );
00120     bindMsg.Call( ipstackRef, sizeof( bindMsg ) );
00121     bindMsg.continuation = ( void * ) sock;
00122 
00123     sockets[sock]->state = CONNECTION_CONNECTING;
00124 
00125     receive( sock );
00126 
00127     return 0;
00128 
00129   }
00130 
00131   else
00132     return -1;
00133 }
00134 
00135 /** Tell the ipstack we want to recieve messages with this function. */
00136 
00137 int Wireless::connect( int sock, const char * ipaddr, int port )
00138 {
00139   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00140        || ( sockets[sock]->trType == SOCK_STREAM && sockets[sock]->state != CONNECTION_CLOSED ) ) return -1;
00141 
00142   sockets[sock]->init();
00143   if (sockets[sock]->trType==SOCK_STREAM) {
00144     // create endpoint
00145     antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, ( sockets[sock]->recvBufSize + sockets[sock]->sendBufSize ) * 3 );
00146     tcpCreateMsg.Call( ipstackRef, sizeof( tcpCreateMsg ) );
00147     if ( tcpCreateMsg.error != ANT_SUCCESS ) return -1;
00148     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00149 
00150     // connect
00151     TCPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, IP_ADDR_ANY, IP_PORT_ANY, ipaddr, port );
00152     connectMsg.continuation = ( void * ) sock;
00153 
00154     connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00155     sockets[sock]->peer_addr=connectMsg.fAddress.Address();
00156     sockets[sock]->peer_port=connectMsg.fPort;
00157 
00158     sockets[sock]->state = CONNECTION_CONNECTING;
00159     return 0;
00160   }
00161 
00162   else if ( sockets[sock]->trType == SOCK_DGRAM )
00163     {
00164       // connect
00165       UDPEndpointConnectMsg connectMsg( sockets[sock]->endpoint, ipaddr, port );
00166 
00167       connectMsg.continuation = ( void * ) sock;
00168 
00169       connectMsg.Send( ipstackRef, myOID, Extra_Entry[entryConnectCont], sizeof( connectMsg ) );
00170       sockets[sock]->peer_addr=connectMsg.address.Address();
00171       sockets[sock]->peer_port=connectMsg.port;
00172 
00173       sockets[sock]->state = CONNECTION_CONNECTED;
00174       //std::cout << "Sock " << sock << " connected via UDP to IP " << ipaddr << " port " << port << std::flush << std::endl;
00175 
00176       return 0;
00177     }
00178 
00179   else
00180     {
00181       return -1;
00182     }
00183 }
00184 
00185 void
00186 Wireless::ListenCont(void* msg)
00187 {
00188 try {
00189   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00190   int sock = ( int )( Msg->continuation );
00191 
00192   if ( sockets[sock]->trType == SOCK_STREAM )
00193     {
00194       TCPEndpointListenMsg * listenMsg = ( TCPEndpointListenMsg * ) msg;
00195 
00196       if ( listenMsg->error != TCP_SUCCESS )
00197         {
00198           sockets[sock]->state = CONNECTION_ERROR;
00199 
00200           // no use recycling since its a resource issue
00201           return;
00202         }
00203       sockets[sock]->peer_addr=listenMsg->fAddress.Address();
00204       sockets[sock]->peer_port=listenMsg->fPort;
00205 
00206       sockets[sock]->state = CONNECTION_CONNECTED;
00207       //sockets[sock]->local_ipaddr = listenMsg->lAddress.Address();
00208       //cout << "Listen set lip: " << local_ipaddr << endl;
00209       receive( sock );
00210     }
00211 
00212 } catch(const std::exception& ex) {
00213   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Listen callback",&ex))
00214     throw;
00215 } catch(...) {
00216   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Listen callback",NULL))
00217     throw;
00218 }
00219 }
00220 
00221 void
00222 Wireless::ConnectCont(void *msg)
00223 {
00224 try {
00225   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00226   int sock = ( int )( Msg->continuation );
00227 
00228   if ( sockets[sock]->trType == SOCK_STREAM )
00229     {
00230       TCPEndpointConnectMsg * connectMsg = ( TCPEndpointConnectMsg * ) msg;
00231       if ( connectMsg->error != TCP_SUCCESS )
00232         {
00233           sockets[sock]->state = CONNECTION_ERROR;
00234           return;
00235         }
00236 
00237       sockets[sock]->state = CONNECTION_CONNECTED;
00238       //sockets[sock]->local_ipaddr = connectMsg->lAddress.Address();
00239       //cout << "Connect set lip: " << local_ipaddr << endl;
00240       receive( sock );
00241     }
00242 
00243 } catch(const std::exception& ex) {
00244   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Connect callback",&ex))
00245     throw;
00246 } catch(...) {
00247   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Connect callback",NULL))
00248     throw;
00249 }
00250 }
00251 
00252 void
00253 Wireless::BindCont(void *msg)
00254 {
00255 try {
00256   UDPEndpointBindMsg* bindMsg = (UDPEndpointBindMsg*)msg;
00257   int sock = (int)bindMsg->continuation;
00258 
00259   if (bindMsg->error != UDP_SUCCESS) {
00260     sockets[sock]->state = CONNECTION_ERROR;
00261     return;
00262   }
00263 
00264   sockets[sock]->state = CONNECTION_CONNECTED;
00265   /*  if(bindMsg->address.Address()!=0) {
00266     //sockets[sock]->local_ipaddr = bindMsg->address.Address();
00267     //cout << "Bind set lip: " << local_ipaddr << endl;
00268   } else {
00269     //cout << "Bind got 0" << endl;
00270     }*/
00271 
00272 } catch(const std::exception& ex) {
00273   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Bind callback",&ex))
00274     throw;
00275 } catch(...) {
00276   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Bind callback",NULL))
00277     throw;
00278 }
00279 }
00280 
00281 void
00282 Wireless::send(int sock)
00283 {
00284   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00285        || sockets[sock]->sendSize <= 0 ) return;
00286 
00287   if ( sockets[sock]->trType == SOCK_STREAM )
00288     {
00289       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00290       sendMsg.continuation = ( void * ) sock;
00291 
00292       sockets[sock]->tx = true;
00293       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( TCPEndpointSendMsg ) );
00294       sockets[sock]->sendSize = 0;
00295     }
00296 
00297   else if ( sockets[sock]->trType == SOCK_DGRAM )
00298     {
00299       UDPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00300 
00301       // this field is just hijacked to id the socket # this message is being sent across
00302       sendMsg.continuation = ( void * ) sock;
00303 
00304       sockets[sock]->tx = true;
00305       sendMsg.Send( ipstackRef, myOID, Extra_Entry[entrySendCont], sizeof( UDPEndpointSendMsg ) );
00306       sockets[sock]->sendSize = 0;
00307     }
00308 }
00309 
00310 void
00311 Wireless::SendCont(void* msg)
00312 {
00313 try {
00314   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00315   int sock = ( int )( Msg->continuation );
00316 
00317   if ( sockets[sock]->trType == SOCK_STREAM )
00318     {
00319       TCPEndpointSendMsg * sendMsg = ( TCPEndpointSendMsg * ) msg;
00320       sockets[sock]->tx = false;
00321       if ( sendMsg->error != TCP_SUCCESS )
00322         {
00323           sockets[sock]->state = CONNECTION_ERROR;
00324           close( sock );
00325           return;
00326         }
00327     }
00328 
00329   else if ( sockets[sock]->trType == SOCK_DGRAM )
00330     {
00331       UDPEndpointSendMsg * sendMsg = ( UDPEndpointSendMsg * ) msg;
00332       sockets[sock]->tx = false;
00333       if ( sendMsg->error != UDP_SUCCESS )
00334         {
00335           sockets[sock]->state = CONNECTION_ERROR;
00336           close( sock );
00337           return;
00338         }
00339     }
00340 
00341   sockets[sock]->flush();
00342 
00343 } catch(const std::exception& ex) {
00344   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Send callback",&ex))
00345     throw;
00346 } catch(...) {
00347   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Send callback",NULL))
00348     throw;
00349 }
00350 }
00351 
00352 /*! @bug This doesn't actually seem to block until the message is
00353 * fully sent... a crash immediately after this will still cause a
00354 * line or two to be dropped.  This is still less dropped than
00355 * regular send, but doesn't do much good for debugging until we fix
00356 * this. (if we can...) */
00357 void
00358 Wireless::blockingSend(int sock)
00359 {
00360   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CONNECTED
00361        || sockets[sock]->sendSize <= 0 ) return;
00362 
00363   if ( sockets[sock]->trType == SOCK_STREAM )
00364     {
00365       TCPEndpointSendMsg sendMsg( sockets[sock]->endpoint, sockets[sock]->sendData, sockets[sock]->sendSize );
00366       sendMsg.continuation = ( void * ) sock;
00367 
00368       sockets[sock]->tx=true;
00369       sockets[sock]->sendSize = 0;
00370       sendMsg.Call( ipstackRef, sizeof( TCPEndpointSendMsg ) );
00371       sockets[sock]->tx = false;
00372     }
00373 
00374   // no double buffering
00375 }
00376 
00377 void
00378 Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) )
00379 {
00380   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL) return;
00381 
00382   sockets[sock]->rcvcbckfn=rcvcbckfn;
00383 }
00384 
00385 void
00386 Wireless::receive(int sock)
00387 {
00388   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00389        || ( sockets[sock]->trType == SOCK_STREAM && sockets[sock]->state != CONNECTION_CONNECTED ) )
00390     return;
00391 
00392   if ( sockets[sock]->trType == SOCK_STREAM )
00393     {
00394       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00395       receiveMsg.continuation = ( void * ) sock;
00396       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00397     }
00398 
00399   else if ( sockets[sock]->trType == SOCK_DGRAM )
00400     {
00401       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00402       receiveMsg.continuation = ( void * ) sock;
00403       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00404     }
00405 
00406   sockets[sock]->rx = true;
00407 }
00408 
00409 void
00410 Wireless::receive(int sock, int (*rcvcbckfn) (char*, int) )
00411 {
00412   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00413       || sockets[sock]->state != CONNECTION_CONNECTED) return;
00414 
00415   sockets[sock]->rcvcbckfn = rcvcbckfn;
00416 
00417   if ( sockets[sock]->trType == SOCK_STREAM )
00418     {
00419       TCPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, 1, sockets[sock]->recvBufSize );
00420       receiveMsg.continuation = ( void * ) sock;
00421       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00422     }
00423 
00424   else if ( sockets[sock]->trType == SOCK_DGRAM )
00425     {
00426       UDPEndpointReceiveMsg receiveMsg( sockets[sock]->endpoint, sockets[sock]->recvData, sockets[sock]->recvBufSize );
00427       receiveMsg.continuation = ( void * ) sock;
00428       receiveMsg.Send( ipstackRef, myOID, Extra_Entry[entryReceiveCont], sizeof( receiveMsg ) );
00429     }
00430 
00431   sockets[sock]->rx = true;
00432 }
00433 
00434 void
00435 Wireless::ReceiveCont(void* msg)
00436 {
00437 try {
00438   // get the socket index before casting the message into UDP or TCP form
00439   antEnvMsg * Msg = ( antEnvMsg * ) msg;
00440   int sock = ( int )( Msg->continuation );
00441 
00442   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00443        || ( sockets[sock]->state != CONNECTION_CONNECTED && sockets[sock]->state != CONNECTION_CONNECTING ) )
00444     return;
00445 
00446   if ( sockets[sock]->trType == SOCK_STREAM )
00447     {
00448       TCPEndpointReceiveMsg * receiveMsg = ( TCPEndpointReceiveMsg * ) msg;
00449       if ( receiveMsg->error != TCP_SUCCESS )
00450         {
00451           sockets[sock]->state = CONNECTION_ERROR;
00452           close( sock );
00453           return;
00454         }
00455 
00456       sockets[sock]->recvSize = receiveMsg->sizeMin;
00457       if ( sockets[sock]->rcvcbckfn != NULL )
00458         sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00459       sockets[sock]->recvSize = 0;
00460 
00461     }
00462 
00463   else if ( sockets[sock]->trType == SOCK_DGRAM )
00464     {
00465       UDPEndpointReceiveMsg * receiveMsg;
00466       receiveMsg = ( UDPEndpointReceiveMsg * ) antEnvMsg::Receive( msg );
00467       sockets[sock]->recvSize = receiveMsg->size;
00468 
00469       if ( receiveMsg->error == UDP_SUCCESS )
00470         {
00471           // if this UDP connection is not connected yet, connect it
00472           // to the address & port of the computer that sent this message.
00473           // This allows us to send UDP messages to any address instead of
00474           // hard-coding a specific address beforehand
00475 
00476           sockets[sock]->peer_addr=receiveMsg->address.Address();
00477           sockets[sock]->peer_port=receiveMsg->port;
00478           if ( !strncmp( "connection request", ( char * ) sockets[sock]->recvData, 18 ) )
00479             {
00480               // clear this message from the receiving buffer
00481               sockets[sock]->recvData += sockets[sock]->recvSize;
00482 
00483               if ( sockets[sock]->state != CONNECTION_CONNECTED )
00484                 {
00485                   char caller[14];
00486                   receiveMsg->address.GetAsString( caller );
00487                   connect( sock, caller, receiveMsg->port );
00488                 }
00489             }
00490 
00491           else if ( sockets[sock]->rcvcbckfn != NULL )
00492             sockets[sock]->rcvcbckfn( ( char * ) sockets[sock]->recvData, sockets[sock]->recvSize );
00493 
00494         }
00495 
00496       sockets[sock]->recvSize = 0;
00497 
00498     }
00499 
00500   receive( sock );
00501 
00502 } catch(const std::exception& ex) {
00503   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Receive callback",&ex))
00504     throw;
00505 } catch(...) {
00506   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Receive callback",NULL))
00507     throw;
00508 }
00509 }
00510 
00511 void
00512 Wireless::close(int sock)
00513 {
00514   if (sockets[sock]->state == CONNECTION_CLOSED ||
00515       sockets[sock]->state == CONNECTION_CLOSING) return;
00516 
00517   if (!(sockets[sock]->server_port>0 && sockets[sock]->daemon)) {
00518     sockets[sock]->recvBuffer.UnMap();
00519     antEnvDestroySharedBufferMsg receiveBufferMsg(sockets[sock]->recvBuffer);
00520     receiveBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00521     sockets[sock]->sendBuffer.UnMap();
00522     antEnvDestroySharedBufferMsg sendBufferMsg(sockets[sock]->sendBuffer);
00523     sendBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00524   }
00525 
00526   if ( sockets[sock]->trType == SOCK_STREAM )
00527     {
00528       TCPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00529       closeMsg.continuation = ( void * ) sock;
00530       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00531     }
00532 
00533   else if ( sockets[sock]->trType == SOCK_DGRAM )
00534     {
00535       UDPEndpointCloseMsg closeMsg( sockets[sock]->endpoint );
00536       closeMsg.continuation = ( void * ) sock;
00537       closeMsg.Send( ipstackRef, myOID, Extra_Entry[entryCloseCont], sizeof( closeMsg ) );
00538     }
00539 
00540   sockets[sock]->peer_addr=sockets[sock]->peer_port=-1;
00541 
00542   sockets[sock]->state = CONNECTION_CLOSING;
00543 }
00544 
00545 uint32
00546 Wireless::getIPAddress(unsigned int /*idx=0*/) {
00547   uint32 local_ipaddr=0;
00548   //from OPEN-R sample ERA201D1Info:
00549   antEnvInitGetParamMsg getParamMsg("ETHER_IP");
00550   getParamMsg.Call(ipstackRef, sizeof(getParamMsg));
00551   if (getParamMsg.error == ANT_SUCCESS && getParamMsg.paramType == antEnv_InitParam_String) {
00552     //cout << "******** RECEIVED " << getParamMsg.value.str << endl;
00553     unsigned int i=0;
00554     for(int j=3; j>=0; j--) {
00555       unsigned int b=0;
00556       while(i<ANTENV_VALUE_LENGTH_MAX && getParamMsg.value.str[i]!='.' && getParamMsg.value.str[i]!='\0')
00557         b=b*10+(getParamMsg.value.str[i++]-'0');
00558       i++; //skip over '.'
00559       local_ipaddr+=b<<(j*8);
00560       //cout << j << ": " << b << ' ' << local_ipaddr << endl;
00561     }
00562   } else {
00563     OSYSLOG1((osyslogERROR,"getParamMsg.Call() FAILED %d", getParamMsg.error));
00564   }
00565   return local_ipaddr;
00566 }
00567 
00568 void
00569 Wireless::CloseCont(void* msg)
00570 {
00571 try {
00572   antEnvMsg * closeMsg = ( antEnvMsg * ) msg;
00573   int sock = ( int )( closeMsg->continuation );
00574   if ( sockets[sock] == NULL )
00575     return;
00576 
00577   sockets[sock]->state = CONNECTION_CLOSED;
00578   sockets[sock]->peer_addr=sockets[sock]->peer_port=-1;
00579   if ( sockets[sock]->server_port > 0 && sockets[sock]->daemon )
00580     {
00581       // recycle if server
00582       listen( sock, sockets[sock]->server_port );
00583     }
00584 
00585   else
00586     {
00587       delete( sockets[sock] );
00588       sockets[sock] = NULL;
00589       freeSockets.push_back( sock );
00590       for(list<int>::iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it)
00591         if(*it==sock) {
00592           usedSockets.erase(it);
00593           break;
00594         }
00595     }
00596 
00597 } catch(const std::exception& ex) {
00598   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Close callback",&ex))
00599     throw;
00600 } catch(...) {
00601   if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during Wireless Close callback",NULL))
00602     throw;
00603 }
00604 }
00605 
00606 #else // PLATFORM_LOCAL
00607 #  include "IPC/Thread.h"
00608 #  include <sys/types.h>
00609 #  include <sys/socket.h>
00610 #  include <netinet/in.h>
00611 #  include <netdb.h>
00612 #  include <arpa/inet.h>
00613 #  include <fcntl.h>
00614 #  include <unistd.h>
00615 #  include <iostream>
00616 #  include <errno.h>
00617 
00618 using namespace std;
00619 
00620 
00621 Wireless::Wireless ()
00622 : interruptChk(-1), interruptCtl(-1), rfds(), wfds(), efds(), fdsMax(0), freeSockets(), usedSockets()
00623 {
00624   sockets[0]=new DummySocket(0);
00625   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00626     sockets[sock]=NULL;
00627     freeSockets.push_back(sock);
00628   }
00629   int p[2];
00630   pipe(p);
00631   interruptChk=p[0];
00632   interruptCtl=p[1];
00633   fdsMax=interruptChk;
00634   if( ::fcntl(interruptChk,F_SETFL,O_NONBLOCK) ==-1 ) {
00635     perror("Wireless::Wireless(): fcntl");
00636   }
00637   FD_ZERO(&rfds);
00638   FD_SET(interruptChk,&rfds);
00639   FD_ZERO(&wfds);
00640   FD_ZERO(&efds);
00641 }
00642 
00643 Wireless::~Wireless ()
00644 {
00645   ThreadNS::Lock l(getLock());
00646 	::close(interruptChk);
00647 	::close(interruptCtl);
00648   interruptChk=interruptCtl=-1;
00649   if(usedSockets.size()>0) {
00650     cerr << "WARNING: Wireless deleted with open Sockets" << endl;
00651     for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00652       delete sockets[*it];
00653       sockets[*it]=NULL;
00654     }
00655     freeSockets.insert(freeSockets.end(),usedSockets.begin(),usedSockets.end());
00656     usedSockets.clear();
00657   }
00658 }
00659 
00660 void Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) ) {
00661   sockets[sock]->rcvcbckfn=rcvcbckfn;
00662 }
00663 
00664 void Wireless::close(int sock) {
00665   ThreadNS::Lock l(getLock());
00666   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL)
00667     return;
00668   sockets[sock]->flush();
00669   sockets[sock]->peer_port = sockets[sock]->peer_addr = -1;
00670   if(sockets[sock]->daemon) {
00671     if(::close(sockets[sock]->endpoint)==-1)
00672       perror("Wireless::close(): close");
00673     sockets[sock]->endpoint=-1;
00674     sockets[sock]->state = CONNECTION_CLOSED;
00675     listen(sock,sockets[sock]->server_port);
00676   } else {
00677     bool found=false;
00678     for(list<int>::iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00679       if(*it==sock) {
00680         usedSockets.erase(it);
00681         found=true;
00682         break;
00683       }
00684     }
00685     if(!found) {
00686       cerr << "WARNING: Could not find socket " << sock << " in usedSockets list of size " << usedSockets.size() << endl;
00687       return;
00688     }
00689     Socket * s=sockets[sock];
00690     sockets[sock] = NULL;
00691     wakeup(s); //avoid select giving error about bad FD
00692     freeSockets.push_back( sock );
00693   }
00694 }
00695 
00696 int Wireless::connect(int sock, const char* ipaddr, int port) {
00697   ThreadNS::Lock l(getLock());
00698   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS
00699        || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CLOSED && sockets[sock]->trType!=SocketNS::SOCK_DGRAM )
00700     return -1;
00701   
00702   if(sockets[sock]->endpoint==-1)
00703     sockets[sock]->init();
00704   int endpoint=sockets[sock]->endpoint;
00705 
00706   sockaddr_in m_addr;
00707   m_addr.sin_family = AF_INET;
00708   m_addr.sin_port = htons ( port );
00709   struct hostent* hostips = gethostbyname(ipaddr);
00710   if ( hostips==NULL) {
00711     cerr << "Wireless::connect(): gethostbyname returned NULL, h_errno==" << h_errno;
00712     switch(h_errno) {
00713     case HOST_NOT_FOUND: cerr << " (HOST_NOT_FOUND)" << endl; break;
00714     case NO_ADDRESS: cerr << " (NO_ADDRESS)" << endl; break;
00715       //case NO_DATA: cerr << " (NO_DATA)" << endl; break; //NO_DATA==NO_ADDRESS
00716     case NO_RECOVERY: cerr << " (NO_RECOVERY)" << endl; break;
00717     case TRY_AGAIN: cerr << " (TRY_AGAIN)" << endl; break;
00718     default: cerr << " (unknown error code!)" << endl; break;
00719     }   
00720     return -1;
00721   }
00722   memcpy(&m_addr.sin_addr,hostips->h_addr_list[0],sizeof(m_addr.sin_addr));
00723   
00724   int status = ::connect ( endpoint, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
00725   if ( status == 0 )
00726     sockets[sock]->state=CONNECTION_CONNECTED;
00727   else if(errno==EINPROGRESS)
00728     sockets[sock]->state=CONNECTION_CONNECTING;
00729   else {
00730     perror("Wireless::connect(): connect");
00731     return -1;
00732   }
00733   sockets[sock]->peer_port = port;
00734   sockets[sock]->peer_addr = ntohl(m_addr.sin_addr.s_addr);
00735   //cout << "connecting " << sockets[sock]->getPeerAddressAsString() << ' ' << sockets[sock]->getPeerPort() << "... " <<status << endl;
00736   //this will allow sock to be added to wfds so we can tell when the connection goes through
00737   wakeup();
00738   return 0;
00739 }
00740 
00741 int Wireless::listen(int sock, int port) {
00742   ThreadNS::Lock l(getLock());
00743   if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS
00744        || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CLOSED )
00745     return -1;
00746   sockets[sock]->server_port = port;
00747   sockets[sock]->init();
00748   int endpoint=sockets[sock]->endpoint;
00749   if ( endpoint<0 )
00750   return -1;
00751   sockaddr_in m_addr;
00752   m_addr.sin_family = AF_INET;
00753   m_addr.sin_addr.s_addr = INADDR_ANY;
00754   m_addr.sin_port = htons ( port );
00755   
00756   int bind_return = ::bind ( endpoint,( struct sockaddr * ) &m_addr,sizeof ( m_addr ) );
00757   if ( bind_return == -1 ) {
00758     perror("Wireless::listen: bind");
00759     return -1;
00760   }
00761   if(sockets[sock]->trType==SocketNS::SOCK_STREAM) {
00762     int listen_return = ::listen ( endpoint, MAXCONNECTIONS );
00763     if ( listen_return == -1 ) {
00764       perror("Wireless::listen: listen");
00765       return -1;
00766     }
00767   }
00768   sockets[sock]->state = CONNECTION_LISTENING;
00769   //this will allow sock to be added to rfds so we can tell when a connection is available
00770   wakeup();
00771   return 0;
00772 }
00773 
00774 Socket* Wireless::socket(TransportType_t ttype) {
00775   return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00776 }
00777 Socket* Wireless::socket(TransportType_t ttype, int recvsize, int sendsize) {
00778   ThreadNS::Lock l(getLock());
00779   if (freeSockets.empty()
00780       || (recvsize + sendsize) <= 256) return sockets[0];
00781   int sock_num=freeSockets.front();
00782   freeSockets.pop_front();
00783   usedSockets.push_back(sock_num);
00784   
00785   sockets[sock_num]=new Socket(sock_num);
00786   
00787   sockets[sock_num]->sendBufSize=sendsize;
00788   sockets[sock_num]->sendBuffer=new char[sockets[sock_num]->sendBufSize*2];
00789   //double buffered sending
00790   sockets[sock_num]->sendData=(byte*)sockets[sock_num]->sendBuffer;
00791   sockets[sock_num]->writeData=(byte*)sockets[sock_num]->sendBuffer+sockets[sock_num]->sendBufSize;
00792 
00793   sockets[sock_num]->recvBufSize=recvsize;
00794   sockets[sock_num]->recvBuffer = new char[sockets[sock_num]->recvBufSize];
00795   sockets[sock_num]->recvData=(byte*)sockets[sock_num]->recvBuffer; //reading is single buffered
00796   
00797   sockets[sock_num]->setTransport(ttype);
00798   
00799   return sockets[sock_num]; 
00800 }
00801 
00802 /*! There's probably better ways to implement this...
00803  *  (run through the interface list?  How does ifconfig do it?) */
00804 uint32 Wireless::getIPAddress(unsigned int idx/*=0*/) {
00805   char buf[ 255 ];
00806   if(gethostname( buf, 255)!=0) {
00807     perror("Wireless::getIPAddress(): gethostname");
00808     return 0;
00809   }
00810   struct hostent * h = gethostbyname( buf );
00811   if(h==NULL) {
00812     herror("Wireless::getIPAddress(): gethostbyname");
00813     return 0;
00814   }
00815   //check to make sure 'idx' is valid
00816   for(unsigned int x=0; x<=idx; x++)
00817     if(h->h_addr_list[x]==NULL)
00818       return 0;
00819   //if we got here, it's valid
00820   return *(uint32*)h->h_addr_list[idx];
00821 }
00822 
00823 void
00824 Wireless::send(int sock)
00825 {
00826   ThreadNS::Lock l(getLock());
00827   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00828       || sockets[sock]->state != CONNECTION_CONNECTED || sockets[sock]->sendSize <= 0 )
00829     return;
00830   
00831   //we could defer all sending to the poll, but let's give a shot at sending it out right away to reduce latency
00832   int s=sockets[sock]->endpoint;
00833   int sent=::send(s,sockets[sock]->sendData+sockets[sock]->sentSize,sockets[sock]->sendSize-sockets[sock]->sentSize,0);
00834   if(sent==-1) {
00835     perror("Wireless::pollProcess(): send");
00836     sockets[sock]->tx = false;
00837     sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00838   } else {
00839     sockets[sock]->sentSize+=sent;
00840     if(sockets[sock]->sentSize==sockets[sock]->sendSize) {
00841       sockets[sock]->tx = false;
00842       sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00843       sockets[sock]->flush();
00844     } else {
00845       sockets[sock]->tx = true;
00846       //more work will be done in poll()
00847       //this will wake up the poll thread to make it check for pending writes (signaled by tx flag)
00848       wakeup();
00849     }
00850   }
00851 }
00852 
00853 void
00854 Wireless::blockingSend(int sock)
00855 {
00856   ThreadNS::Lock l(getLock());
00857   if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00858       || sockets[sock]->state != CONNECTION_CONNECTED || sockets[sock]->sendSize <= 0 )
00859     return;
00860   
00861   while(sockets[sock]->sentSize<sockets[sock]->sendSize) {
00862     fd_set bs_wfds;
00863     FD_ZERO(&bs_wfds);
00864     FD_SET(sockets[sock]->endpoint, &bs_wfds);
00865     int retval = select(sockets[sock]->endpoint+1, NULL, &bs_wfds, NULL, NULL);
00866     if(retval==0)
00867       continue;
00868     if(retval==-1) {
00869       perror("Wireless::poll(): select");
00870       return;
00871     }
00872     if(sockets[sock]->tx) //block on leftover non-blocking send
00873       continue;
00874     int sent=::send(sockets[sock]->endpoint,sockets[sock]->sendData+sockets[sock]->sentSize,sockets[sock]->sendSize-sockets[sock]->sentSize,0);
00875     if(sent==-1) {
00876       if(errno==EAGAIN) {
00877         cerr << "Wireless::blockingSend(): send() was not ready, even though select() said it was" << endl;
00878         continue;
00879       }
00880       perror("Wireless::blockingSend(): send");
00881       sockets[sock]->tx = false;
00882       sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00883       return;
00884     }
00885     sockets[sock]->sentSize+=sent;
00886   }
00887   sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00888 }
00889 
00890 void Wireless::pollSetup() {
00891   FD_ZERO(&rfds);
00892   FD_ZERO(&wfds);
00893   FD_ZERO(&efds);
00894   FD_SET(interruptChk, &rfds);
00895 
00896   fdsMax=interruptChk;
00897   ThreadNS::Lock l(getLock());
00898   //cout << "pollSetup " << usedSockets.size() << endl;
00899   for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00900     if(sockets[*it]==NULL) {
00901       cerr << "ERROR: Wireless::pollSetup() encountered NULL socket " << *it << endl;
00902       continue;
00903     }
00904     if(sockets[*it]->endpoint==-1) {
00905       cerr << "ERROR Wireless::pollSetup() encountered bad endpoint " << *it << endl;
00906       continue;
00907     }
00908     if(sockets[*it]->state!=CONNECTION_CLOSED && sockets[*it]->state!=CONNECTION_ERROR)
00909       FD_SET(sockets[*it]->endpoint, &rfds);
00910     if(sockets[*it]->state==CONNECTION_CONNECTING || sockets[*it]->tx)
00911       FD_SET(sockets[*it]->endpoint, &wfds);
00912     FD_SET(sockets[*it]->endpoint, &efds);
00913     if(sockets[*it]->endpoint>fdsMax)
00914       fdsMax=sockets[*it]->endpoint;
00915   }
00916 }
00917 
00918 /*! @param tv  how long to wait -- NULL will wait indefinitely until a socket event occurs
00919  *  @return true if there was a socket event to process, false if timed out */
00920 bool Wireless::pollTest(struct timeval* tv) {
00921   int retval = select(fdsMax+1, &rfds, &wfds, &efds, tv);
00922   if(retval==-1)
00923     perror("Wireless::pollTest(): select");
00924   return (retval!=0);
00925 }
00926 
00927 void Wireless::pollProcess() {
00928   ThreadNS::Lock l(getLock());
00929   if(FD_ISSET(interruptChk,&rfds)) {
00930     //wakeup sent to handle non-blocking write
00931     int res=1;
00932     //cout << "Clearing interrupts..." << flush;
00933     while(res>0) {
00934       Socket * del=NULL;
00935       res=::read(interruptChk,&del,sizeof(del));
00936       //cout << ' ' << del << flush;
00937       if(del!=NULL)
00938         delete del;
00939     }
00940     //cout << " done" << endl;
00941   }
00942   for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00943     if(sockets[*it]==NULL) {
00944       cerr << "NULL socket " << *it << endl;
00945       continue;
00946     }
00947     if(sockets[*it]->endpoint==-1) {
00948       cerr << "bad endpoint " << *it << endl;
00949       continue;
00950     }
00951     int s=sockets[*it]->endpoint;
00952     if(FD_ISSET(s,&rfds)) {
00953       //cout << *it << " set in read" << endl;
00954       if(sockets[*it]->state==CONNECTION_CONNECTING) {
00955         //cout << "Wireless::pollProcess(): read set on connecting" << endl;
00956         sockets[*it]->state=CONNECTION_CONNECTED;
00957       }
00958       if(sockets[*it]->state==CONNECTION_LISTENING) {
00959         if(sockets[*it]->trType==SocketNS::SOCK_STREAM) {
00960           sockaddr_in m_addr;
00961           socklen_t addrlen=sizeof(m_addr);
00962           int n=accept(s,(sockaddr*)&m_addr,&addrlen);
00963           if(n==-1) {
00964             perror("Wireless::pollProcess(): accept");
00965             continue;
00966           }
00967           sockets[*it]->peer_addr=ntohl(m_addr.sin_addr.s_addr);
00968           sockets[*it]->peer_port=ntohs(m_addr.sin_port);
00969           //this closes the server socket -- we'll want to address this
00970           if(::close(s)==-1)
00971             perror("Wireless::pollProcess(): close");
00972           s=sockets[*it]->endpoint=n;
00973           sockets[*it]->state=CONNECTION_CONNECTED;
00974           //cout << "Accepted connection" << endl;
00975         } else {
00976           //cout << "UDP accept" << endl;
00977           sockaddr_in m_addr;
00978           socklen_t addrlen=sizeof(m_addr);
00979           sockets[*it]->recvSize = recvfrom(s,sockets[*it]->recvData,sockets[*it]->recvBufSize,0,(sockaddr*)&m_addr,&addrlen);
00980           if(sockets[*it]->recvSize==-1) {
00981             perror("Wireless::pollProcess(): acception recvfrom");
00982             continue;
00983           }
00984           /* //this can cause trouble for broadcasts... we'll make the user call 'connect' themselves if they want to send back
00985            //cout << "connecting..." << endl;
00986           int ret = ::connect ( s, (sockaddr*) &m_addr, sizeof ( m_addr ) );
00987           if ( ret==-1 && errno!=EINPROGRESS ) {
00988             perror("Wireless::pollProcess(): connect");
00989             continue;
00990           }
00991           //cout << "UDP accepted!" << endl;
00992           sockets[*it]->state=CONNECTION_CONNECTING;
00993            */
00994           sockets[*it]->peer_addr=ntohl(m_addr.sin_addr.s_addr);
00995           sockets[*it]->peer_port=ntohs(m_addr.sin_port);
00996           if(sockets[*it]->recvSize!=0) {
00997             //cout << "Read " << sockets[*it]->recvSize << " bytes " << sockets[*it]->rcvcbckfn << endl;
00998             if ( !strncmp( "connection request", ( char * ) sockets[*it]->recvData, 18 ) ) {
00999               // clear this message from the receiving buffer
01000               if ( sockets[*it]->state != CONNECTION_CONNECTED )
01001                 connect( *it, sockets[*it]->getPeerAddressAsString().c_str(), sockets[*it]->getPeerPort() );
01002             } else if ( sockets[*it]->rcvcbckfn != NULL ) {
01003               try {
01004                 sockets[*it]->rcvcbckfn( ( char * ) sockets[*it]->recvData, sockets[*it]->recvSize );
01005               } catch(const std::exception& ex) {
01006                 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",&ex))
01007                   throw;
01008               } catch(...) {
01009                 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",NULL))
01010                   throw;
01011               }
01012             }
01013             sockets[*it]->recvSize = 0;
01014           }
01015         }
01016       } else  if(sockets[*it]->state==CONNECTION_CONNECTED || sockets[*it]->state==CONNECTION_CLOSING) {
01017         sockets[*it]->recvSize = recvfrom(s,sockets[*it]->recvData,sockets[*it]->recvBufSize,0,NULL,NULL);
01018         if(sockets[*it]->recvSize==-1) {
01019           if(errno!=EAGAIN) { //may have just completed connection, not a problem
01020             if(errno==ECONNREFUSED) {
01021               cerr << "connection refused: endpoint=" << s << " sock=" << *it << " Socket=" << sockets[*it] << endl;
01022               list<int>::const_iterator tmp=it;
01023               //a UDP server could come in here
01024               if(!sockets[*it]->daemon) //don't decrement if the socket is going to stay open
01025                 --it;
01026               close(*tmp);
01027               continue;
01028             }
01029             perror("Wireless::pollProcess(): recvfrom");
01030           }
01031         } else if(sockets[*it]->recvSize==0) {
01032           list<int>::const_iterator tmp=it--;
01033           close(*tmp);
01034           //cout << "closed connection" << endl;
01035           continue;
01036         } else {
01037           //cout << "Read " << sockets[*it]->recvSize << " bytes " << sockets[*it]->rcvcbckfn << endl;
01038           if ( sockets[*it]->rcvcbckfn != NULL ) {
01039             try {
01040               sockets[*it]->rcvcbckfn( ( char * ) sockets[*it]->recvData, sockets[*it]->recvSize );
01041             } catch(const std::exception& ex) {
01042               if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",&ex))
01043                 throw;
01044             } catch(...) {
01045               if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",NULL))
01046                 throw;
01047             }
01048           }
01049           sockets[*it]->recvSize = 0;
01050         }
01051       } else {
01052         int dropped=0,n=0;
01053         char buf[100];
01054         while((n=recvfrom(s,buf,100,0,NULL,NULL))>0)
01055           dropped+=n;
01056         cerr << "Wireless::pollProcess(): socket (sys=" << s << ", tk="<<*it<<") read flag in bad state (" << sockets[*it]->state << "), " << dropped << " bytes were dropped, ending with:" << endl;
01057         for(int i=0; i<n; i++)
01058           if(isprint(buf[i]))
01059             cerr << buf[i];
01060           else
01061             cerr << '.';
01062         cerr << endl;
01063       }
01064     }
01065     if(FD_ISSET(s,&wfds)) {
01066       //cout << *it << " set in write" << endl;
01067       if(sockets[*it]->state==CONNECTION_CONNECTING) {
01068         sockets[*it]->state=CONNECTION_CONNECTED;
01069       } else if(sockets[*it]->state==CONNECTION_CONNECTED) {
01070         if(!sockets[*it]->tx) {
01071           //cerr << "Wireless::pollProcess(): write available on non-tx socket??" << endl;
01072           //can happen on a refused connection
01073         } else {
01074           int sent=::send(s,sockets[*it]->sendData+sockets[*it]->sentSize,sockets[*it]->sendSize-sockets[*it]->sentSize,0);
01075           if(sent==-1) {
01076             perror("Wireless::pollProcess(): send");
01077             sockets[*it]->tx = false;
01078             sockets[*it]->sendSize = sockets[*it]->sentSize = 0;
01079           } else {
01080             sockets[*it]->sentSize+=sent;
01081             if(sockets[*it]->sentSize==sockets[*it]->sendSize) {
01082               sockets[*it]->tx = false;
01083               sockets[*it]->sendSize = sockets[*it]->sentSize = 0;
01084               sockets[*it]->flush();
01085             }
01086           }
01087         }
01088       } else {
01089         cerr << "Wireless::pollProcess(): socket write flag in bad state" << endl;
01090       }
01091     }
01092     if(FD_ISSET(s,&efds)) {
01093       cerr << "Socket exception: " << flush;
01094       int err=0;
01095       socklen_t errlen=sizeof(err);
01096       if ( ::getsockopt ( s, SOL_SOCKET, SO_ERROR, &err, &errlen ) == -1 ) {
01097         perror("Wireless::processPoll(): getsockopt");
01098       }
01099       cerr << err << " endpoint=" << s << " sock=" << *it << " Socket=" << sockets[*it] << endl;
01100     }
01101   }
01102 }
01103 
01104 /*! @param del if non-NULL, will cause the socket to be closed and deleted */
01105 void Wireless::wakeup(Socket * del/*=NULL*/) {
01106   ::write(interruptCtl,&del,sizeof(del)); 
01107 }
01108 
01109 ThreadNS::Lock& Wireless::getLock() {
01110   static ThreadNS::Lock lock;
01111   return lock;
01112 }
01113 
01114 #endif
01115 
01116 /*! @file
01117  * @brief Interacts with the system to provide networking services
01118  * @author alokl (Creator)
01119  * @author Erik Berglund and Bryan Johnson (UDP support)
01120  * 
01121  * @verbinclude CMPack_license.txt
01122  *
01123  * $Author: ejt $
01124  * $Name: tekkotsu-2_4_1 $
01125  * $Revision: 1.27 $
01126  * $State: Exp $
01127  * $Date: 2005/08/16 18:37:05 $
01128  */
01129 

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