Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Socket.cc

Go to the documentation of this file.
00001 #include "Socket.h"
00002 #include <stdio.h>
00003 #include "Wireless.h"
00004 #ifndef PLATFORM_APERIOS
00005 #  include "IPC/Thread.h"
00006 #  include <sys/types.h>
00007 #  include <sys/socket.h>
00008 #  include <netinet/in.h>
00009 #  include <netdb.h>
00010 #  include <arpa/inet.h>
00011 #  include <fcntl.h>
00012 #endif
00013 #include "Shared/Config.h"
00014 #include "Shared/MarkScope.h"
00015 #include <unistd.h>
00016 
00017 Socket* sout=NULL;
00018 Socket* serr=NULL;
00019 
00020 int Socket::setTransport(TransportType_t tr) {
00021 #ifdef PLATFORM_APERIOS
00022   trType=tr;
00023 #else
00024   if(trType==tr && endpoint!=-1)
00025     return 0;
00026   trType=tr;
00027   init();
00028 #endif
00029   return 0;
00030 }
00031 
00032 
00033 Socket::~Socket() {
00034 #ifndef PLATFORM_APERIOS
00035   if(endpoint!=-1)
00036     ::close ( endpoint );
00037   if(recvBuffer!=NULL)
00038     delete [] recvBuffer;
00039   if(sendBuffer!=NULL)
00040     delete [] sendBuffer;
00041 #endif
00042 }
00043 
00044 byte*
00045 Socket::getWriteBuffer(int bytesreq)
00046 {
00047 #ifndef PLATFORM_APERIOS
00048   MarkScope l(wireless->getLock());
00049 #endif
00050   byte* buf=NULL;
00051   if (sendBufSize-writeSize>=bytesreq
00052       && state==CONNECTION_CONNECTED)
00053     buf=writeData+writeSize;
00054   else if (state!=CONNECTION_CONNECTED) {
00055     if(forwardSock!=NULL)
00056       buf=forwardSock->getWriteBuffer(bytesreq);
00057     else if(textForward)
00058       buf=(byte*)(textForwardBuf=new char[bytesreq]);
00059   }
00060 #ifndef PLATFORM_APERIOS
00061   // the lock is about to expire as we leave, but if buf is
00062   // valid, we want to retain the lock until write() is called
00063   if(buf!=NULL)
00064     wireless->getLock().useResource(Resource::emptyData);
00065 #endif
00066   return buf;
00067 }
00068 
00069 void
00070 Socket::write(int size)
00071 {
00072 #ifndef PLATFORM_APERIOS
00073 #  ifdef DEBUG
00074   //we should be coming in with a lock from getWriteBuffer...
00075   if(Thread::Lock * lock=dynamic_cast<Thread::Lock*>(&wireless->getLock())) {
00076     if(lock->getLockLevel()==0) {
00077       serr->printf("Socket: Attempted write() without previously successful getWriteBuffer()\n");
00078       return;
00079     }
00080   }
00081 #  endif
00082 #endif
00083   writeSize+=size;
00084   if(textForwardBuf) {
00085 		::write(STDOUT_FILENO,textForwardBuf,size);
00086     delete textForwardBuf;
00087     textForwardBuf=NULL;
00088   } else
00089     flush();
00090 #ifndef PLATFORM_APERIOS
00091   wireless->getLock().releaseResource(Resource::emptyData);
00092 #endif
00093 }
00094 
00095 int
00096 Socket::read()
00097 {
00098   return -1;
00099 }
00100 
00101 byte*
00102 Socket::getReadBuffer()
00103 {
00104   return NULL;
00105 //  return readData+readSize;
00106 }
00107 
00108 void
00109 Socket::init()
00110 {
00111 #ifndef PLATFORM_APERIOS
00112   MarkScope l(wireless->getLock());
00113 #endif
00114   sendSize=0;
00115   writeSize=0;
00116   peer_addr=peer_port=-1;
00117 #ifndef PLATFORM_APERIOS
00118   if(endpoint!=-1)
00119     if(::close(endpoint)==-1)
00120       perror("Wireless::close(): close");
00121   state = CONNECTION_CLOSED;
00122   endpoint = ::socket ( AF_INET,trType,0 );
00123   if(endpoint==-1) {
00124     perror("Socket::init(): socket()");
00125     return;
00126   }
00127   // TIME_WAIT - argh
00128   int on = 1;
00129   if ( ::setsockopt ( endpoint, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00130     perror("Socket::init(): SO_REUSEADDR setsockopt");
00131   }
00132   if(trType==Socket::SOCK_DGRAM) {
00133     if ( ::setsockopt ( endpoint, SOL_SOCKET, SO_BROADCAST, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00134       perror("Socket::init(): SO_BROADCAST setsockopt");
00135     }
00136     const int sndbuf=(1<<16)-28;
00137     if ( ::setsockopt ( endpoint, SOL_SOCKET, SO_SNDBUF, ( const char* ) &sndbuf, sizeof ( sndbuf ) ) == -1 ) {
00138       perror("Socket::init(): SO_SNDBUF setsockopt");
00139     }
00140   }
00141   if( ::fcntl(endpoint,F_SETFL,O_NONBLOCK) ==-1 ) {
00142     perror("Socket::init(): fcntl");
00143   }
00144 #endif
00145 }
00146 
00147 int
00148 Socket::setFlushType(FlushType_t fType)
00149 {
00150   if (state != CONNECTION_CLOSED) return -1;
00151   flType=fType;
00152   return 0;
00153 }
00154 
00155 void
00156 Socket::flush()
00157 {
00158 #ifndef PLATFORM_APERIOS
00159   MarkScope l(wireless->getLock());
00160 #endif
00161   if (state!=CONNECTION_CONNECTED) {
00162     if(forwardSock!=NULL)
00163       return forwardSock->flush();
00164   } else {
00165     if (flType==FLUSH_NONBLOCKING) {
00166       if (!tx) {
00167         byte *tempData=sendData;
00168         int tempSize=sendSize;
00169         sendData=writeData;
00170         writeData=tempData;
00171         sendSize=writeSize;
00172         writeSize=tempSize;
00173         wireless->send(sock);
00174       }
00175     } else {
00176       sendData=writeData;
00177       sendSize=writeSize;
00178       wireless->blockingSend(sock);
00179       writeSize=0;
00180     }
00181   }
00182 }
00183 
00184 int
00185 Socket::pprintf(int vlevel, const char *fmt, ...)
00186 {
00187   if (vlevel>verbosity) return 0;
00188 
00189   int ret;
00190   va_list al;
00191   va_start(al,fmt);
00192   ret=this->printf(fmt, al); 
00193   va_end(al);
00194 
00195   return ret;
00196 }
00197 
00198 int
00199 Socket::printf(const char *fmt, ...)
00200 {
00201   va_list al;
00202   va_start(al,fmt);
00203   int ret=vprintf(fmt,al);
00204   va_end(al);
00205   return ret;
00206 }
00207 
00208 int
00209 Socket::vprintf(const char *fmt, va_list al)
00210 {
00211   /*
00212   if (state==CONNECTION_CONNECTED && (sendBufSize-writeSize<256)) {
00213     flush();
00214     if (sendBufSize-writeSize<256)
00215       return -1;
00216   }*/
00217 
00218   if (state!=CONNECTION_CONNECTED) {
00219     if(forwardSock!=NULL)
00220       return forwardSock->vprintf(fmt,al);
00221     if(textForward)
00222       return vfprintf(stdout, fmt, al);
00223   } else {
00224 #ifndef PLATFORM_APERIOS
00225     MarkScope l(wireless->getLock());
00226 #endif
00227     int ret=vsnprintf((char *)(writeData+writeSize), sendBufSize-writeSize, fmt, al);
00228     writeSize+=ret;
00229     flush();
00230     return ret;
00231   }
00232   return -1;
00233 }
00234 
00235 int
00236 Socket::write(const byte *buf, int size)
00237 {
00238   if (state!=CONNECTION_CONNECTED) {
00239     if(forwardSock!=NULL)
00240       return forwardSock->write(buf,size);
00241     if(textForward)
00242       return ::write(STDOUT_FILENO,buf,size);
00243   } else {
00244 #ifndef PLATFORM_APERIOS
00245     MarkScope l(wireless->getLock());
00246 #endif
00247     byte *destbuf=getWriteBuffer(size);
00248     if (destbuf==NULL) return -1;
00249     memcpy(destbuf, buf, size);
00250     write(size);
00251     return size;
00252   }
00253   return -1;
00254 }
00255 
00256 int
00257 Socket::read(byte * /*buf*/, int /*size*/)
00258 {  
00259 /*  if (size>=recvBufSize-recvPos) return -1;
00260   memcpy(buf,recvData+recvPos,size);*/
00261   return -1;
00262 }
00263 
00264 std::string Socket::getPeerAddressAsString() const {
00265   char buf[20];
00266   snprintf(buf,20,"%hhu.%hhu.%hhu.%hhu",(unsigned char)(peer_addr>>24),(unsigned char)(peer_addr>>16),(unsigned char)(peer_addr>>8),(unsigned char)peer_addr);
00267   //const unsigned char *b=(const unsigned char*)&peer_addr;
00268   //snprintf(buf,20,"%hhu.%hhu.%hhu.%hhu",b[0],b[1],b[2],b[3]);
00269   //snprintf(buf,20,"%hhu.%hhu.%hhu.%hhu",peer_addr&0xFF,(peer_addr>>8)&0xFF,(peer_addr>>16)&0xFF,(peer_addr>>24)&0xFF);
00270   return buf;
00271 }
00272 
00273 /*! @file
00274  * @brief Implements Tekkotsu wireless Socket class, also sout and serr
00275  * @author alokl (Creator)
00276  */
00277 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:51 2016 by Doxygen 1.6.3