Homepage Demos Overview Downloads Tutorials Reference
Credits

Wireless.cc

Go to the documentation of this file.
00001 
00002 #include <OPENR/OSyslog.h>
00003 #include <OPENR/OPENRAPI.h>
00004 #include <ant.h>
00005 #include <EndpointTypes.h>
00006 #include <TCPEndpointMsg.h>
00007 #include <UDPEndpointMsg.h>
00008 #include <string.h>
00009 #include "Wireless.h"
00010 #include "Socket.h"
00011 #include "MMCombo/entry.h"
00012 
00013 using namespace SocketNS;
00014 
00015 Wireless *wireless=NULL;
00016 
00017 Wireless::Wireless ()
00018   : ipstackRef(), myOID(), freeSockets()
00019 {
00020   ipstackRef = antStackRef("IPStack");
00021   WhoAmI(&myOID);
00022 
00023   sockets[0]=new DummySocket(0);
00024   for (int sock = 1; sock < WIRELESS_MAX_SOCKETS; sock++) {
00025     sockets[sock]=NULL;
00026     freeSockets.push_back(sock);
00027   }
00028 }    
00029 
00030 Wireless::~Wireless ()
00031 {
00032   // TODO
00033 }
00034 
00035 Socket* Wireless::socket(TransportType_t ttype)
00036 {
00037   return socket(ttype, WIRELESS_DEF_RECV_SIZE, WIRELESS_DEF_SEND_SIZE);
00038 }
00039 
00040 Socket* Wireless::socket(TransportType_t ttype, int recvsize, int sendsize)
00041 {
00042   if (freeSockets.empty()
00043       || (recvsize + sendsize) <= 256) return sockets[0];
00044   int sock_num=freeSockets.front();
00045   freeSockets.pop_front();
00046 
00047   sockets[sock_num]=new Socket(sock_num);
00048   sockets[sock_num]->trType=ttype;
00049   sockets[sock_num]->sendBufSize=sendsize;
00050   sockets[sock_num]->recvBufSize=recvsize;
00051 
00052   // setup send buffer
00053   antEnvCreateSharedBufferMsg sendBufferMsg(sendsize*2);
00054   sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00055   if (sendBufferMsg.error != ANT_SUCCESS) return sockets[0];
00056   
00057   sockets[sock_num]->sendBuffer = sendBufferMsg.buffer;
00058   sockets[sock_num]->sendBuffer.Map();
00059   sockets[sock_num]->sendData
00060         = (byte*)(sockets[sock_num]->sendBuffer.GetAddress());
00061 
00062   // setup receive buffer
00063   antEnvCreateSharedBufferMsg recvBufferMsg(recvsize*2);
00064   recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00065   if (recvBufferMsg.error != ANT_SUCCESS) return sockets[0];
00066   
00067   sockets[sock_num]->recvBuffer = recvBufferMsg.buffer;
00068   sockets[sock_num]->recvBuffer.Map();
00069   sockets[sock_num]->recvData
00070         = (byte*)(sockets[sock_num]->recvBuffer.GetAddress());
00071 
00072   sockets[sock_num]->readData=sockets[sock_num]->recvData+recvsize;
00073   sockets[sock_num]->writeData=sockets[sock_num]->sendData+sendsize;
00074 
00075   return sockets[sock_num]; 
00076 }
00077 
00078 int Wireless::listen(int sock, int port)
00079 {
00080   if (port<=0 || port>=65535
00081       || sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00082       || sockets[sock]->state != CONNECTION_CLOSED) return -1;
00083   
00084   sockets[sock]->server_port=port;
00085   sockets[sock]->init();
00086 
00087   if (sockets[sock]->trType==SOCK_STREAM) {
00088     // create endpoint
00089     antEnvCreateEndpointMsg tcpCreateMsg(EndpointType_TCP,
00090                                          (sockets[sock]->recvBufSize+
00091                                          sockets[sock]->sendBufSize)*3);
00092     tcpCreateMsg.Call(ipstackRef, sizeof(tcpCreateMsg));
00093     if (tcpCreateMsg.error != ANT_SUCCESS) return -1;
00094     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00095 
00096     // listen
00097     TCPEndpointListenMsg listenMsg(sockets[sock]->endpoint,
00098                                    IP_ADDR_ANY, port);
00099     listenMsg.continuation = (void*)sock;
00100 
00101     listenMsg.Send(ipstackRef, myOID,
00102                    Extra_Entry[entryListenCont], sizeof(listenMsg));
00103     
00104     sockets[sock]->state = CONNECTION_LISTENING;
00105     return 0;
00106   } else if (sockets[sock]->trType==SOCK_DGRAM) {
00107     // create endpoint
00108     antEnvCreateEndpointMsg udpCreateMsg(EndpointType_UDP,
00109                                          (sockets[sock]->recvBufSize+
00110                                          sockets[sock]->sendBufSize)*3);
00111     udpCreateMsg.Call(ipstackRef, sizeof(udpCreateMsg));
00112     if (udpCreateMsg.error != ANT_SUCCESS) return -1;
00113     sockets[sock]->endpoint = udpCreateMsg.moduleRef;
00114 
00115     // bind
00116     UDPEndpointBindMsg bindMsg(sockets[sock]->endpoint,
00117                                    IP_ADDR_ANY, port);
00118     bindMsg.continuation = (void*)sock;
00119 
00120     bindMsg.Send(ipstackRef, myOID,
00121                  Extra_Entry[entryBindCont], sizeof(bindMsg));
00122     
00123     sockets[sock]->state = CONNECTION_LISTENING;
00124     return 0;
00125   } else {
00126     return -1;
00127   }
00128 }
00129 
00130 int Wireless::connect(int sock, const char* ipaddr, int port)
00131 {
00132   if (port<=0 || port>=65535
00133       || sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00134       || sockets[sock]->state != CONNECTION_CLOSED) return -1;
00135   
00136   sockets[sock]->init();
00137   if (sockets[sock]->trType==SOCK_STREAM) {
00138     // create endpoint
00139     antEnvCreateEndpointMsg tcpCreateMsg(EndpointType_TCP,
00140                                          (sockets[sock]->recvBufSize+
00141                                          sockets[sock]->sendBufSize)*3);
00142     tcpCreateMsg.Call(ipstackRef, sizeof(tcpCreateMsg));
00143     if (tcpCreateMsg.error != ANT_SUCCESS) return -1;
00144     sockets[sock]->endpoint = tcpCreateMsg.moduleRef;
00145 
00146     // connect
00147     TCPEndpointConnectMsg connectMsg(sockets[sock]->endpoint,
00148                                     IP_ADDR_ANY, IP_PORT_ANY, ipaddr, port);
00149     connectMsg.continuation = (void*)sock;
00150 
00151     connectMsg.Send(ipstackRef, myOID,
00152                     Extra_Entry[entryConnectCont], sizeof(connectMsg));
00153     
00154     sockets[sock]->state = CONNECTION_CONNECTING;
00155     return 0;
00156   } else if (sockets[sock]->trType==SOCK_DGRAM) {
00157     //TODO
00158     return 0;
00159   } else {
00160     return -1;
00161   }
00162 }
00163 
00164 void
00165 Wireless::ListenCont(void* msg)
00166 {
00167   TCPEndpointListenMsg* listenMsg = (TCPEndpointListenMsg*)msg;
00168   int sock = (int)listenMsg->continuation;
00169 
00170   if (listenMsg->error != TCP_SUCCESS) {
00171     sockets[sock]->state = CONNECTION_ERROR;
00172     // no use recycling since its a resource issue
00173     return;
00174   }
00175 
00176   sockets[sock]->state = CONNECTION_CONNECTED;
00177   if (sockets[sock]->rcvcbckfn) { receive(sock); }
00178 }
00179 
00180 void
00181 Wireless::ConnectCont(void *msg)
00182 {
00183   TCPEndpointConnectMsg* connectMsg = (TCPEndpointConnectMsg*)msg;
00184   int sock = (int)connectMsg->continuation;
00185 
00186   if (connectMsg->error != TCP_SUCCESS) {
00187     sockets[sock]->state = CONNECTION_ERROR;
00188     return;
00189   }
00190   
00191   sockets[sock]->state = CONNECTION_CONNECTED;
00192   if (sockets[sock]->rcvcbckfn) { receive(sock); }  //Thanks to Andrew Cristina <acristin@cs.uno.edu>, et. al. for bug fix
00193 }
00194 
00195 void
00196 Wireless::BindCont(void *msg)
00197 {
00198   UDPEndpointBindMsg* bindMsg = (UDPEndpointBindMsg*)msg;
00199   int sock = (int)bindMsg->continuation;
00200 
00201   if (bindMsg->error != UDP_SUCCESS) {
00202     sockets[sock]->state = CONNECTION_ERROR;
00203     return;
00204   }
00205 
00206   sockets[sock]->state = CONNECTION_CONNECTED;
00207 }
00208 
00209 void
00210 Wireless::send(int sock)
00211 {
00212   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00213       || sockets[sock]->state != CONNECTION_CONNECTED
00214       || sockets[sock]->sendSize <= 0) return;
00215 
00216     TCPEndpointSendMsg sendMsg(sockets[sock]->endpoint,
00217                                sockets[sock]->sendData,
00218                                sockets[sock]->sendSize);
00219     sendMsg.continuation = (void*)sock;
00220 
00221     sockets[sock]->tx=true;
00222     sendMsg.Send(ipstackRef, myOID,
00223                  Extra_Entry[entrySendCont],
00224                  sizeof(TCPEndpointSendMsg));
00225     sockets[sock]->sendSize = 0;
00226 }
00227 
00228 void
00229 Wireless::SendCont(void* msg)
00230 {
00231     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*)msg;
00232     int sock = (int)(sendMsg->continuation);
00233 
00234     sockets[sock]->tx=false;
00235     if (sendMsg->error != TCP_SUCCESS) {
00236       sockets[sock]->state=CONNECTION_ERROR;
00237       close(sock);
00238       return;
00239     }
00240     sockets[sock]->flush();
00241 }
00242 
00243 /*! @bug This doesn't actually seem to block until the message is
00244  *  fully sent... a crash immediately after this will still cause a
00245  *  line or two to be dropped.  This is still less dropped than
00246  *  regular send, but doesn't do much good for debugging until we fix
00247  *  this. (if we can...) */
00248 void
00249 Wireless::blockingSend(int sock)
00250 {
00251   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00252       || sockets[sock]->state != CONNECTION_CONNECTED
00253       || sockets[sock]->sendSize <= 0) return;
00254 
00255     TCPEndpointSendMsg sendMsg(sockets[sock]->endpoint,
00256                                sockets[sock]->sendData,
00257                                sockets[sock]->sendSize);
00258     sendMsg.continuation = (void*)sock;
00259 
00260     sockets[sock]->tx=true;
00261     sockets[sock]->sendSize = 0;
00262     sendMsg.Call(ipstackRef, sizeof(TCPEndpointSendMsg));
00263     sockets[sock]->tx=false;
00264     // no double buffering
00265 }
00266 
00267 void
00268 Wireless::setReceiver(int sock, int (*rcvcbckfn) (char*, int) )
00269 {
00270   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL) return;
00271 
00272   sockets[sock]->rcvcbckfn=rcvcbckfn;
00273 }
00274 
00275 void
00276 Wireless::receive(int sock)
00277 {
00278   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00279       || sockets[sock]->state != CONNECTION_CONNECTED) return;
00280   
00281   TCPEndpointReceiveMsg receiveMsg(sockets[sock]->endpoint,
00282                                    sockets[sock]->recvData,
00283                                    1,sockets[sock]->recvBufSize);
00284   receiveMsg.continuation = (void*)sock;
00285 
00286   receiveMsg.Send(ipstackRef, myOID,
00287                   Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
00288 
00289   sockets[sock]->rx=true;
00290 }
00291 
00292 void
00293 Wireless::receive(int sock, int (*rcvcbckfn) (char*, int) )
00294 {
00295   if (sock<=0 || sock>=WIRELESS_MAX_SOCKETS || sockets[sock]==NULL
00296       || sockets[sock]->state != CONNECTION_CONNECTED) return;
00297 
00298   sockets[sock]->rcvcbckfn=rcvcbckfn;
00299   
00300   TCPEndpointReceiveMsg receiveMsg(sockets[sock]->endpoint,
00301                                    sockets[sock]->recvData,
00302                                    1,sockets[sock]->recvBufSize);
00303   receiveMsg.continuation = (void*)sock;
00304 
00305   receiveMsg.Send(ipstackRef, myOID,
00306                   Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
00307   sockets[sock]->rx=true;
00308 }
00309 
00310 void
00311 Wireless::ReceiveCont(void* msg)
00312 {
00313     TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*)msg;
00314     int sock = (int)(receiveMsg->continuation);
00315 
00316     if (receiveMsg->error != TCP_SUCCESS) {
00317       sockets[sock]->state=CONNECTION_ERROR;
00318       close(sock);
00319       return;
00320     }
00321     sockets[sock]->recvSize=receiveMsg->sizeMin;
00322     sockets[sock]->rcvcbckfn((char*)sockets[sock]->recvData,
00323                              sockets[sock]->recvSize);
00324     sockets[sock]->recvSize=0;
00325     receive(sock);
00326 }
00327 
00328 void
00329 Wireless::close(int sock)
00330 {
00331   if (sockets[sock]->state == CONNECTION_CLOSED ||
00332       sockets[sock]->state == CONNECTION_CLOSING) return;
00333 
00334   if (!(sockets[sock]->server_port>0 && sockets[sock]->daemon)) {
00335     sockets[sock]->recvBuffer.UnMap();
00336     antEnvDestroySharedBufferMsg receiveBufferMsg(sockets[sock]->recvBuffer);
00337     receiveBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00338     sockets[sock]->sendBuffer.UnMap();
00339     antEnvDestroySharedBufferMsg sendBufferMsg(sockets[sock]->sendBuffer);
00340     sendBufferMsg.Call(ipstackRef, sizeof(antEnvDestroySharedBufferMsg));
00341   }
00342 
00343   TCPEndpointCloseMsg closeMsg(sockets[sock]->endpoint);
00344   closeMsg.continuation = (void*)sock;
00345 
00346   closeMsg.Send(ipstackRef, myOID,
00347       Extra_Entry[entryCloseCont], sizeof(closeMsg));
00348 
00349   sockets[sock]->state = CONNECTION_CLOSING;
00350 }
00351 
00352 void
00353 Wireless::CloseCont(void* msg)
00354 {
00355   TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*)msg;
00356   int sock = (int)(closeMsg->continuation);
00357   if(sockets[sock]==NULL)
00358     return;
00359 
00360   sockets[sock]->state = CONNECTION_CLOSED;
00361   if (sockets[sock]->server_port>0
00362       && sockets[sock]->daemon) {
00363     // recycle if server
00364     listen(sock, sockets[sock]->server_port);
00365   } else {
00366     delete(sockets[sock]);
00367     sockets[sock]=NULL;
00368     freeSockets.push_back(sock);
00369   }
00370 }
00371 
00372 /*! @file
00373  * @brief Interacts with the system to provide networking services
00374  * @author alokl (Creator)
00375  * 
00376  * @verbinclude CMPack_license.txt
00377  *
00378  * $Author: ejt $
00379  * $Name: tekkotsu-2_1 $
00380  * $Revision: 1.16 $
00381  * $State: Exp $
00382  * $Date: 2003/12/11 05:49:31 $
00383  */
00384 

Tekkotsu v2.1
Generated Tue Mar 16 23:19:16 2004 by Doxygen 1.3.5