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
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
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
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
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
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
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
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
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
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
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
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 * ) antEnvMsg::Receive( msg );
00195
00196 if ( listenMsg->error != TCP_SUCCESS )
00197 {
00198 sockets[sock]->state = CONNECTION_ERROR;
00199
00200
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
00208
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 * ) antEnvMsg::Receive( 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
00239
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*) antEnvMsg::Receive( 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
00266
00267
00268
00269
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
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 * ) antEnvMsg::Receive( 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 * ) antEnvMsg::Receive( 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
00353
00354
00355
00356
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
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
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 * ) antEnvMsg::Receive( 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
00472
00473
00474
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
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 ) {
00547 uint32 local_ipaddr=0;
00548
00549 antEnvInitGetParamMsg getParamMsg("ETHER_IP");
00550 getParamMsg.Call(ipstackRef, sizeof(getParamMsg));
00551 if (getParamMsg.error == ANT_SUCCESS && getParamMsg.paramType == antEnv_InitParam_String) {
00552
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++;
00559 local_ipaddr+=b<<(j*8);
00560
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 * ) antEnvMsg::Receive( 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
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 # include "Shared/MarkScope.h"
00618
00619 using namespace std;
00620
00621
00622 Wireless::Wireless ()
00623 : callbackLock(NULL), interruptChk(-1), interruptCtl(-1), rfds(), wfds(), efds(), fdsMax(0), freeSockets(), usedSockets()
00624 {
00625 sockets[0]=new DummySocket(0);
00626 for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00627 sockets[sock]=NULL;
00628 freeSockets.push_back(sock);
00629 }
00630 int p[2];
00631 pipe(p);
00632 interruptChk=p[0];
00633 interruptCtl=p[1];
00634 fdsMax=interruptChk;
00635 if( ::fcntl(interruptChk,F_SETFL,O_NONBLOCK) ==-1 ) {
00636 perror("Wireless::Wireless(): fcntl");
00637 }
00638 FD_ZERO(&rfds);
00639 FD_SET(interruptChk,&rfds);
00640 FD_ZERO(&wfds);
00641 FD_ZERO(&efds);
00642 }
00643
00644 Wireless::~Wireless ()
00645 {
00646 MarkScope l(getLock());
00647 ::close(interruptChk);
00648 ::close(interruptCtl);
00649 interruptChk=interruptCtl=-1;
00650 if(usedSockets.size()>0) {
00651 cerr << "WARNING: Wireless deleted with open Sockets" << endl;
00652 for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00653 delete sockets[*it];
00654 sockets[*it]=NULL;
00655 }
00656 freeSockets.insert(freeSockets.end(),usedSockets.begin(),usedSockets.end());
00657 usedSockets.clear();
00658 }
00659 delete sockets[0];
00660 }
00661
00662 void Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) ) {
00663 sockets[sock]->rcvcbckfn=rcvcbckfn;
00664 }
00665
00666 void Wireless::close(int sock) {
00667 MarkScope l(getLock());
00668 if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL)
00669 return;
00670 sockets[sock]->flush();
00671 sockets[sock]->peer_port = sockets[sock]->peer_addr = -1;
00672 if(sockets[sock]->daemon) {
00673 sockets[sock]->init();
00674 listen(sock,sockets[sock]->server_port);
00675 } else {
00676 bool found=false;
00677 for(list<int>::iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00678 if(*it==sock) {
00679 usedSockets.erase(it);
00680 found=true;
00681 break;
00682 }
00683 }
00684 if(!found) {
00685 cerr << "WARNING: Could not find socket " << sock << " in usedSockets list of size " << usedSockets.size() << endl;
00686 return;
00687 }
00688 Socket * s=sockets[sock];
00689 sockets[sock] = NULL;
00690 wakeup(s);
00691 freeSockets.push_back( sock );
00692 }
00693 }
00694
00695 int Wireless::connect(int sock, const char* ipaddr, int port) {
00696 MarkScope l(getLock());
00697 if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS
00698 || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CLOSED && sockets[sock]->trType!=SocketNS::SOCK_DGRAM )
00699 return -1;
00700
00701 if(sockets[sock]->endpoint==-1)
00702 sockets[sock]->init();
00703 int endpoint=sockets[sock]->endpoint;
00704
00705 sockaddr_in m_addr;
00706 m_addr.sin_family = AF_INET;
00707 m_addr.sin_port = htons ( port );
00708 struct hostent* hostips = gethostbyname(ipaddr);
00709 if ( hostips==NULL) {
00710 cerr << "Wireless::connect(): gethostbyname returned NULL, h_errno==" << h_errno;
00711 switch(h_errno) {
00712 case HOST_NOT_FOUND: cerr << " (HOST_NOT_FOUND)" << endl; break;
00713 case NO_ADDRESS: cerr << " (NO_ADDRESS)" << endl; break;
00714
00715 case NO_RECOVERY: cerr << " (NO_RECOVERY)" << endl; break;
00716 case TRY_AGAIN: cerr << " (TRY_AGAIN)" << endl; break;
00717 default: cerr << " (unknown error code!)" << endl; break;
00718 }
00719 return -1;
00720 }
00721 memcpy(&m_addr.sin_addr,hostips->h_addr_list[0],sizeof(m_addr.sin_addr));
00722
00723 int status = ::connect ( endpoint, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
00724 if ( status == 0 )
00725 sockets[sock]->state=CONNECTION_CONNECTED;
00726 else if(errno==EINPROGRESS)
00727 sockets[sock]->state=CONNECTION_CONNECTING;
00728 else {
00729 perror("Wireless::connect(): connect");
00730 return -1;
00731 }
00732 sockets[sock]->peer_port = port;
00733 sockets[sock]->peer_addr = ntohl(m_addr.sin_addr.s_addr);
00734
00735
00736 wakeup();
00737 return 0;
00738 }
00739
00740 int Wireless::listen(int sock, int port) {
00741 MarkScope l(getLock());
00742 if ( port <= 0 || port >= 65535 || sock <= 0 || sock >= WIRELESS_MAX_SOCKETS
00743 || sockets[sock] == NULL || sockets[sock]->state != CONNECTION_CLOSED )
00744 return -1;
00745 sockets[sock]->server_port = port;
00746 sockets[sock]->init();
00747 int endpoint=sockets[sock]->endpoint;
00748 if ( endpoint<0 )
00749 return -1;
00750 sockaddr_in m_addr;
00751 m_addr.sin_family = AF_INET;
00752 m_addr.sin_addr.s_addr = INADDR_ANY;
00753 m_addr.sin_port = htons ( port );
00754
00755 int bind_return = ::bind ( endpoint,( struct sockaddr * ) &m_addr,sizeof ( m_addr ) );
00756 if ( bind_return == -1 ) {
00757 perror("Wireless::listen: bind");
00758 return -1;
00759 }
00760 if(sockets[sock]->trType==SocketNS::SOCK_STREAM) {
00761 int listen_return = ::listen ( endpoint, MAXCONNECTIONS );
00762 if ( listen_return == -1 ) {
00763 perror("Wireless::listen: listen");
00764 return -1;
00765 }
00766 }
00767 sockets[sock]->state = CONNECTION_LISTENING;
00768
00769 wakeup();
00770 return 0;
00771 }
00772
00773 Socket* Wireless::socket(TransportType_t ttype) {
00774 return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00775 }
00776 Socket* Wireless::socket(TransportType_t ttype, int recvsize, int sendsize) {
00777 MarkScope l(getLock());
00778 if (freeSockets.empty()
00779 || (recvsize + sendsize) <= 256) return sockets[0];
00780 int sock_num=freeSockets.front();
00781 freeSockets.pop_front();
00782 usedSockets.push_back(sock_num);
00783
00784 sockets[sock_num]=new Socket(sock_num);
00785
00786 sockets[sock_num]->sendBufSize=sendsize;
00787 sockets[sock_num]->sendBuffer=new char[sockets[sock_num]->sendBufSize*2];
00788
00789 sockets[sock_num]->sendData=(byte*)sockets[sock_num]->sendBuffer;
00790 sockets[sock_num]->writeData=(byte*)sockets[sock_num]->sendBuffer+sockets[sock_num]->sendBufSize;
00791
00792 sockets[sock_num]->recvBufSize=recvsize;
00793 sockets[sock_num]->recvBuffer = new char[sockets[sock_num]->recvBufSize];
00794 sockets[sock_num]->recvData=(byte*)sockets[sock_num]->recvBuffer;
00795
00796 sockets[sock_num]->setTransport(ttype);
00797
00798 return sockets[sock_num];
00799 }
00800
00801
00802
00803 uint32 Wireless::getIPAddress(unsigned int idx) {
00804 char buf[ 255 ];
00805 if(gethostname( buf, 255)!=0) {
00806 perror("Wireless::getIPAddress(): gethostname");
00807 return 0;
00808 }
00809 struct hostent * h = gethostbyname( buf );
00810 if(h==NULL) {
00811 herror("Wireless::getIPAddress(): gethostbyname");
00812 return 0;
00813 }
00814
00815 for(unsigned int x=0; x<=idx; x++)
00816 if(h->h_addr_list[x]==NULL)
00817 return 0;
00818
00819 return *(uint32*)h->h_addr_list[idx];
00820 }
00821
00822 void
00823 Wireless::send(int sock)
00824 {
00825 MarkScope l(getLock());
00826 if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00827 || sockets[sock]->state != CONNECTION_CONNECTED || sockets[sock]->sendSize <= 0 )
00828 return;
00829
00830
00831 int s=sockets[sock]->endpoint;
00832 int sent=::send(s,sockets[sock]->sendData+sockets[sock]->sentSize,sockets[sock]->sendSize-sockets[sock]->sentSize,0);
00833 if(sent==-1) {
00834 if(errno==ECONNREFUSED) {
00835 close(sock);
00836 } else {
00837 perror("Wireless::send(): send");
00838 cerr << "Wireless::send() data size was " << sockets[sock]->sendSize-sockets[sock]->sentSize << endl;
00839 sockets[sock]->tx = false;
00840 sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00841 }
00842 } else {
00843 sockets[sock]->sentSize+=sent;
00844 if(sockets[sock]->sentSize==sockets[sock]->sendSize) {
00845 sockets[sock]->tx = false;
00846 sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00847 sockets[sock]->flush();
00848 } else {
00849 sockets[sock]->tx = true;
00850
00851
00852 wakeup();
00853 }
00854 }
00855 }
00856
00857 void
00858 Wireless::blockingSend(int sock)
00859 {
00860 MarkScope l(getLock());
00861 if ( sock <= 0 || sock >= WIRELESS_MAX_SOCKETS || sockets[sock] == NULL
00862 || sockets[sock]->state != CONNECTION_CONNECTED || sockets[sock]->sendSize <= 0 )
00863 return;
00864
00865 while(sockets[sock]->sentSize<sockets[sock]->sendSize) {
00866 fd_set bs_wfds;
00867 FD_ZERO(&bs_wfds);
00868 FD_SET(sockets[sock]->endpoint, &bs_wfds);
00869 int retval = select(sockets[sock]->endpoint+1, NULL, &bs_wfds, NULL, NULL);
00870 if(retval==0)
00871 continue;
00872 if(retval==-1) {
00873 perror("Wireless::poll(): select");
00874 return;
00875 }
00876 if(sockets[sock]->tx)
00877 continue;
00878 int sent=::send(sockets[sock]->endpoint,sockets[sock]->sendData+sockets[sock]->sentSize,sockets[sock]->sendSize-sockets[sock]->sentSize,0);
00879 if(sent==-1) {
00880 if(errno==EAGAIN) {
00881 cerr << "Wireless::blockingSend(): send() was not ready, even though select() said it was" << endl;
00882 continue;
00883 }
00884 perror("Wireless::blockingSend(): send");
00885 sockets[sock]->tx = false;
00886 sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00887 return;
00888 }
00889 sockets[sock]->sentSize+=sent;
00890 }
00891 sockets[sock]->sendSize = sockets[sock]->sentSize = 0;
00892 }
00893
00894 void Wireless::pollSetup() {
00895 FD_ZERO(&rfds);
00896 FD_ZERO(&wfds);
00897 FD_ZERO(&efds);
00898 FD_SET(interruptChk, &rfds);
00899
00900 fdsMax=interruptChk;
00901 MarkScope l(getLock());
00902
00903 for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00904 if(sockets[*it]==NULL) {
00905 cerr << "ERROR: Wireless::pollSetup() encountered NULL socket " << *it << endl;
00906 continue;
00907 }
00908 if(sockets[*it]->endpoint==-1) {
00909 cerr << "ERROR Wireless::pollSetup() encountered bad endpoint " << *it << endl;
00910 continue;
00911 }
00912 if(sockets[*it]->state!=CONNECTION_CLOSED && sockets[*it]->state!=CONNECTION_ERROR)
00913 FD_SET(sockets[*it]->endpoint, &rfds);
00914 if(sockets[*it]->state==CONNECTION_CONNECTING || sockets[*it]->tx)
00915 FD_SET(sockets[*it]->endpoint, &wfds);
00916 FD_SET(sockets[*it]->endpoint, &efds);
00917 if(sockets[*it]->endpoint>fdsMax)
00918 fdsMax=sockets[*it]->endpoint;
00919 }
00920 }
00921
00922
00923
00924 bool Wireless::pollTest(struct timeval* tv) {
00925 int retval = select(fdsMax+1, &rfds, &wfds, &efds, tv);
00926 if(retval==-1)
00927 perror("Wireless::pollTest(): select");
00928 return (retval!=0);
00929 }
00930
00931 void Wireless::pollProcess() {
00932 MarkScope cl(getCallbackLock());
00933 MarkScope l(getLock());
00934 if(FD_ISSET(interruptChk,&rfds)) {
00935
00936 int res=1;
00937
00938 while(res>0) {
00939 Socket * del=NULL;
00940 res=::read(interruptChk,&del,sizeof(del));
00941
00942 if(del!=NULL)
00943 delete del;
00944 }
00945
00946 }
00947 for(list<int>::const_iterator it=usedSockets.begin(); it!=usedSockets.end(); ++it) {
00948 if(sockets[*it]==NULL) {
00949 cerr << "NULL socket " << *it << endl;
00950 continue;
00951 }
00952 if(sockets[*it]->endpoint==-1) {
00953 cerr << "bad endpoint " << *it << endl;
00954 continue;
00955 }
00956 int s=sockets[*it]->endpoint;
00957 if(FD_ISSET(s,&rfds)) {
00958
00959 if(sockets[*it]->state==CONNECTION_CONNECTING) {
00960
00961 sockets[*it]->state=CONNECTION_CONNECTED;
00962 }
00963 if(sockets[*it]->state==CONNECTION_LISTENING) {
00964 if(sockets[*it]->trType==SocketNS::SOCK_STREAM) {
00965 sockaddr_in m_addr;
00966 socklen_t addrlen=sizeof(m_addr);
00967 int n=accept(s,(sockaddr*)&m_addr,&addrlen);
00968 if(n==-1) {
00969 if(errno!=EAGAIN)
00970 perror("Wireless::pollProcess(): accept");
00971 continue;
00972 }
00973 sockets[*it]->peer_addr=ntohl(m_addr.sin_addr.s_addr);
00974 sockets[*it]->peer_port=ntohs(m_addr.sin_port);
00975
00976 if(::close(s)==-1)
00977 perror("Wireless::pollProcess(): close");
00978 s=sockets[*it]->endpoint=n;
00979 sockets[*it]->state=CONNECTION_CONNECTED;
00980
00981 } else {
00982
00983 sockaddr_in m_addr;
00984 socklen_t addrlen=sizeof(m_addr);
00985 sockets[*it]->recvSize = recvfrom(s,sockets[*it]->recvData,sockets[*it]->recvBufSize,0,(sockaddr*)&m_addr,&addrlen);
00986 if(sockets[*it]->recvSize==-1) {
00987 perror("Wireless::pollProcess(): acception recvfrom");
00988 continue;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 sockets[*it]->peer_addr=ntohl(m_addr.sin_addr.s_addr);
01001 sockets[*it]->peer_port=ntohs(m_addr.sin_port);
01002 if(sockets[*it]->recvSize!=0) {
01003
01004 if ( !strncmp( "connection request", ( char * ) sockets[*it]->recvData, 18 ) ) {
01005
01006 if ( sockets[*it]->state != CONNECTION_CONNECTED )
01007 connect( *it, sockets[*it]->getPeerAddressAsString().c_str(), sockets[*it]->getPeerPort() );
01008 } else if ( sockets[*it]->rcvcbckfn != NULL ) {
01009 try {
01010 sockets[*it]->rcvcbckfn( ( char * ) sockets[*it]->recvData, sockets[*it]->recvSize );
01011 } catch(const std::exception& ex) {
01012 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",&ex))
01013 throw;
01014 } catch(...) {
01015 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",NULL))
01016 throw;
01017 }
01018 }
01019 sockets[*it]->recvSize = 0;
01020 }
01021 }
01022 } else if(sockets[*it]->state==CONNECTION_CONNECTED || sockets[*it]->state==CONNECTION_CLOSING) {
01023 sockets[*it]->recvSize = recvfrom(s,sockets[*it]->recvData,sockets[*it]->recvBufSize,0,NULL,NULL);
01024 if(sockets[*it]->recvSize==-1) {
01025 if(errno!=EAGAIN) {
01026 if(errno==ECONNREFUSED || errno==ECONNRESET) {
01027
01028 list<int>::const_iterator tmp=it;
01029
01030 if(!sockets[*it]->daemon)
01031 --it;
01032 close(*tmp);
01033 continue;
01034 }
01035 perror("Wireless::pollProcess(): recvfrom");
01036 }
01037 } else if(sockets[*it]->recvSize==0) {
01038 list<int>::const_iterator tmp=it--;
01039 close(*tmp);
01040
01041 continue;
01042 } else {
01043
01044 if ( sockets[*it]->rcvcbckfn != NULL ) {
01045 try {
01046 sockets[*it]->rcvcbckfn( ( char * ) sockets[*it]->recvData, sockets[*it]->recvSize );
01047 } catch(const std::exception& ex) {
01048 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",&ex))
01049 throw;
01050 } catch(...) {
01051 if(!ProjectInterface::uncaughtException(__FILE__,__LINE__,"Occurred during networking received data callback",NULL))
01052 throw;
01053 }
01054 }
01055 sockets[*it]->recvSize = 0;
01056 }
01057 } else {
01058 int dropped=0,n=0;
01059 char buf[100];
01060 while((n=recvfrom(s,buf,100,0,NULL,NULL))>0)
01061 dropped+=n;
01062 cerr << "Wireless::pollProcess(): socket (sys=" << s << ", tk="<<*it<<") read flag in bad state (" << sockets[*it]->state << "), " << dropped << " bytes were dropped, ending with:" << endl;
01063 for(int i=0; i<n; i++)
01064 if(isprint(buf[i]))
01065 cerr << buf[i];
01066 else
01067 cerr << '.';
01068 cerr << endl;
01069 }
01070 }
01071 if(FD_ISSET(s,&wfds)) {
01072
01073 if(sockets[*it]->state==CONNECTION_CONNECTING) {
01074 sockets[*it]->state=CONNECTION_CONNECTED;
01075 } else if(sockets[*it]->state==CONNECTION_CONNECTED) {
01076 if(!sockets[*it]->tx) {
01077
01078
01079 } else {
01080 int sent=::send(s,sockets[*it]->sendData+sockets[*it]->sentSize,sockets[*it]->sendSize-sockets[*it]->sentSize,0);
01081 if(sent==-1) {
01082 perror("Wireless::pollProcess(): send");
01083 sockets[*it]->tx = false;
01084 sockets[*it]->sendSize = sockets[*it]->sentSize = 0;
01085 } else {
01086 sockets[*it]->sentSize+=sent;
01087 if(sockets[*it]->sentSize==sockets[*it]->sendSize) {
01088 sockets[*it]->tx = false;
01089 sockets[*it]->sendSize = sockets[*it]->sentSize = 0;
01090 sockets[*it]->flush();
01091 }
01092 }
01093 }
01094 } else {
01095 cerr << "Wireless::pollProcess(): socket write flag in bad state" << endl;
01096 }
01097 }
01098 if(FD_ISSET(s,&efds)) {
01099 cerr << "Socket exception: " << flush;
01100 int err=0;
01101 socklen_t errlen=sizeof(err);
01102 if ( ::getsockopt ( s, SOL_SOCKET, SO_ERROR, &err, &errlen ) == -1 ) {
01103 perror("Wireless::processPoll(): getsockopt");
01104 }
01105 cerr << err << " endpoint=" << s << " sock=" << *it << " Socket=" << sockets[*it] << endl;
01106 }
01107 }
01108 }
01109
01110
01111 void Wireless::wakeup(Socket * del) {
01112 ::write(interruptCtl,&del,sizeof(del));
01113 }
01114
01115 Resource& Wireless::getLock() {
01116 static ThreadNS::Lock lock;
01117 return lock;
01118 }
01119
01120 void Wireless::setCallbackLock(Resource& l) {
01121 MarkScope pcl(getCallbackLock());
01122 callbackLock=&l;
01123 }
01124
01125 void Wireless::clearCallbackLock() {
01126 callbackLock=NULL;
01127 }
01128
01129 #endif
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145