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
00062
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
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
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
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
00213
00214
00215
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 * , int )
00258 {
00259
00260
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
00268
00269
00270 return buf;
00271 }
00272
00273
00274
00275
00276
00277