Wireless.ccGo 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
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 * ) 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 * ) 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*)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 * ) 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
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 * ) 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 * ) 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
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);
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
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
00736
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
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
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;
00796
00797 sockets[sock_num]->setTransport(ttype);
00798
00799 return sockets[sock_num];
00800 }
00801
00802
00803
00804 uint32 Wireless::getIPAddress(unsigned int idx) {
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
00816 for(unsigned int x=0; x<=idx; x++)
00817 if(h->h_addr_list[x]==NULL)
00818 return 0;
00819
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
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
00847
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)
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
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
00919
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
00931 int res=1;
00932
00933 while(res>0) {
00934 Socket * del=NULL;
00935 res=::read(interruptChk,&del,sizeof(del));
00936
00937 if(del!=NULL)
00938 delete del;
00939 }
00940
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
00954 if(sockets[*it]->state==CONNECTION_CONNECTING) {
00955
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
00970 if(::close(s)==-1)
00971 perror("Wireless::pollProcess(): close");
00972 s=sockets[*it]->endpoint=n;
00973 sockets[*it]->state=CONNECTION_CONNECTED;
00974
00975 } else {
00976
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
00985
00986
00987
00988
00989
00990
00991
00992
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
00998 if ( !strncmp( "connection request", ( char * ) sockets[*it]->recvData, 18 ) ) {
00999
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) {
01020 if(errno==ECONNREFUSED) {
01021 cerr << "connection refused: endpoint=" << s << " sock=" << *it << " Socket=" << sockets[*it] << endl;
01022 list<int>::const_iterator tmp=it;
01023
01024 if(!sockets[*it]->daemon)
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
01035 continue;
01036 } else {
01037
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
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
01072
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
01105 void Wireless::wakeup(Socket * del) {
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
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
|